home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / c / awin / awin.c < prev    next >
Text File  |  1999-05-17  |  151KB  |  5,209 lines

  1. /* awin.c 1.0.13
  2.  
  3. todo:
  4.  - test depth 16 directdraw with cv3d (modulo should be ok, but
  5.    I'm not 100% sure)
  6.  - implement window open/close hooks with possiblity to pass
  7.    extra taglist to OpenWindowTags (for menus etc)
  8.  - write 0x0 optimized versions of _awddscalech68k16,
  9.    _awddremapscalech68k16, _awddscalech68k16_565,
  10.    _awddscalech68k16_argb and awchunky2planarham6
  11.  - add dithered 565->332 conversions (needed?)
  12.  - add triplebuffering (needed?)
  13.  - fixedsize flag (don't scale, don't allow window resize,
  14.    or screenmodereq, width and height arguments ignored)
  15.  - set pending quitflag in awrenderchunky if srcdepth change
  16.    fails and check this flag in awhandleinput
  17.  - add awismrFilterFunc_hookentry support for ppc version
  18.  - argparser: if windowmode adjust width & height to
  19.    1:1 aspect ratio (use awodargs default dimensions to get ar)
  20.  - key to set current window size as default
  21.  - implement jump to (next?) pubscreen
  22.  
  23. new features since last release:
  24.  - implemented ARGB for depth 16, now window and non-directdraw
  25.    screen mode have real 16bit output.
  26.  - extensively tested on my brand new BVisionPPC,
  27.    1280x1024 16bit wb on 21" monitor seriously kicks ass :-)
  28.  
  29. bugfixes since last release:
  30.  v1.0.13
  31.  - now uses DIPF_IS_HAM trick to get native default monitor
  32.  - gfxcard and forcenative disables fblit check (speed issues)
  33.  - forcenative + useham caused problems with CGFX/P96
  34.  - *awiwbReadArgs /T didn't allow 1 for true and 0 for false
  35.  - didn't set palette for 16bit screen
  36.  - CGFX/P96 16bit directdraw was buggy due missing
  37.    display->pixperrow/=2;
  38.  - finally fixed awreadargs flag update
  39.  v1.0.12
  40.  - awallocbm should now change task ln_name ppc combatible way
  41.  - awallocbm didn't check for pr_CLI -> fblit wasn't detected
  42.    if awin was started from Workbench
  43.  - awsetpalette didn't respect stoprender.
  44.  - WriteLUTPixelArray used wrong palette with 16bit emu.
  45.  - heart of 16bit->8bit system, awrgb16to332, was wrong, it
  46.    lost all red bits :)
  47.  - fixed rgb565->rgb332 remapscale 1:1
  48.  - DIPF_IS_WB prevented selection of HAM modes.
  49.  - finally found the nasty timer havoc from PPC code:
  50.    PPCSub64 is fukken BUGGED! for example PPCSub64 thinks
  51.    1c00011f79 - 1b40eede5c = 1bf12411d ... erm, maybe not!
  52.    PPCSub64 doesn't handle lower long overflow condition
  53.    correctly. how lame. replaced with own code.
  54.  - really fixed PPC 'CyberGraphX 3+ PIXFMT_RGB16 not available' bug,
  55.    it was because of unpatched (geninclude.pl)
  56.    gg:ppc-amigaos/os-include/cybergraphx/cybergraphics.h
  57.    struct CyberModeNode
  58.  - fixed ppc timer wraparound bug
  59.  v1.0.11
  60.  - due stupid mistake you could not turn off dbuffering hmmph :)
  61.  - fixed lockpubscreen fallback
  62.  - found out that also SAS/C ppc fucks up os structure
  63.    alignment. hmph
  64.  - ppc had probs with INVALID_ID because it's ~0 and thus
  65.    negative. fixed with #undef INVALID_ID #define INVALID_ID
  66.    (0xffffffffUL). "<Piru_> Zuikkis, siellä o jotain häröä :)"
  67.  - there was no 'display->native=1; display->cgfx=0;' code
  68.    in awigetscreentype, and this caused problems with cgfx +
  69.    native modes. Thanks to zuulkuul for reporting this problem :)
  70.  - took ages to figure out that Libnix-PPC makes os structure
  71.    alignment fuck up. damn it! :-( maybe libRILC then
  72.  v1.0.10
  73.  - added some fixed GG includes
  74.  - improved awin.doc
  75.  - added AW_SCALEDEBUG to help scale debugging
  76.  - doesn't choke anymore if CloseScreen() fails, instead
  77.    will DisplayBeep, Delay and retry until successful.
  78.  - ouch, directdraw didn't wait safetowrite
  79.  v1.0.9
  80.  - fixed some ddazure2.ASM overflows
  81.  - no more does awremap on window resize
  82.  - improved awin.doc a bit
  83.  - ddazure2.ASM/_awddremapscalech68k8 .samex trashed 12(a5)
  84.    and 4(a5) with given a5. hillos to Asa who experienced some
  85.    crashes because of this. :)
  86.  v1.0.8
  87.  - had (!display->truecolor) in awremap window mode, it
  88.    broke wlutpa fallback code (it didn't alloc pens)
  89.  v1.0.7
  90.  - now you can choose only valid screenmodes with screenmodereq
  91.  - implemented proper (I hope) modeid validation
  92.  - added bunch of missing TAG_DONEs
  93.  - preparing some stuff for 16bit support, also fixed argument
  94.    parser accordingly
  95.  - fixed lots of display->pixperrow=display->width; to
  96.    display->pixperrow=display->width_align;
  97.    now window resize should work again on wlutpa systems.
  98.    (now YOU can shoot me for that mistake, thanks to Duken
  99.    who apparently was the only one to resize the window... :)
  100.  - made awsetpalette again NOT clear window on screen mode,
  101.    I rely on coder doing palette changes correctly. now palette
  102.    fades are possible (screen mode only tho)
  103.  v1.0.6
  104.  - oops, added __saveds to awismrFilterFunc_hookentry,
  105.    it broke without when awindemo grew out of smalldata
  106.  - hmpph. whoever convinced me that it doesn't make sense to
  107.    use dbuffer with directdraw will be shot. I wish I wouldn't
  108.    need to shoot myself.
  109.  - added modulo support to awscalechunky
  110.  v1.0.5
  111.  - (bpr&0xf==0) -> ((bpr&0xf)==0) now directdraw works. Thanks
  112.    to Duken who kindly recompiled bugfixed version.
  113.  v1.0.4
  114.  - there were no bugs. honest ;)
  115.  v1.0.3
  116.  - added fallback code here and there
  117.  - general code cleanup
  118.  v1.0.2
  119.  - now checks DIPF_IS_DBUFFER before buffering
  120.  - fixed to gracefully fall back to native mode if some unknown
  121.    gfxsystem (CGFX V2 for example)
  122.  - fixed CGFX doublebuffer to render correct bitmap
  123.  - fixed awremap to check palentries and screen
  124.  - fixed screenbuffer port cleanup
  125.  
  126. notes:
  127.  - first CyberGraphX 4's were bugged I heard
  128.  - c2p is used on native screen mode
  129.  - c2p+blit is used on native window mode if fblit is running
  130.    or there is no WCP/WPA8 patch installed
  131.  - if there is no WCP/WPA8 patch or fblit running window
  132.    mode flickers quite a lot, also interleaved screen reduces
  133.    flicker
  134.  - keys:
  135.    ESC Q quit
  136.    W     switch to window mode
  137.    S     switch to screen mode
  138.    TAB   toggle between window and screen mode
  139.    P     pause rendering (handy for screenshots;)
  140.    SPACE readjust window size/pos so that it has original w&h
  141.    M     change screen mode ModeID (also changes window size)
  142.  
  143. suggestions:
  144.  - always have correct 68040 (and 68060) libraries installed
  145.  - always run SetPatch before running awin programs
  146.  - on native systems use fblit and NewWPA8 for best performance
  147.  - if CGXAGA seems utterly slow get NewWPA8 from aminet
  148.    (however native AGA mode IS faster than CGXAGA)
  149.  
  150. legal mushmush:
  151.  - see awin.doc/--introduction--
  152.  
  153. */
  154.  
  155. /*
  156.     ;rrrrrggg gggbbbbb rrrrrggg gggbbbbb 565 565
  157.     ;to
  158.     ;rrrgggbb rrrgggbb 332 332
  159.  
  160.     moveq    #16,d7
  161.  
  162.     move.l    #~(1<<(2+16)),d5
  163.     and.l    (a1)+,d5 ;1 rrrxxggg yyybb0zz rrrxxggg yyybbzzz
  164.     move.l    (a1)+,d6 ;2 rrrxxggg yyybbzzz rrrxxggg yyybbzzz
  165.     bra    .goxlop
  166.  
  167. .xlop    move.l    (a1)+,d5 ;1 rrrxxggg yyybb0zz rrrxxggg yyybbzzz
  168.     move.l    (a1)+,d6 ;2 rrrxxggg yyybbzzz rrrxxggg yyybbzzz
  169.     and.l    #~(1<<(2+16)),d5
  170.     move.l    d4,(a0)+
  171. .goxlop
  172.     lsl.b    #3,d5    ;1 rrrxxggg yyybb0zz rrrxxggg bbzzz000
  173.     lsl.b    #3,d6    ;2 rrrxxggg yyybbzzz rrrxxggg bbzzz000
  174.     lsr.w    #5,d5    ;1 rrrxxggg yyybb0zz 00000rrr xxgggbbz
  175.     lsr.w    #5,d6    ;2 rrrxxggg yyybbzzz 00000rrr xxgggbbz
  176.     lsl.b    #2,d5    ;1 rrrxxggg yyybb0zz 00000rrr gggbbz00
  177.     lsl.b    #2,d6    ;2 rrrxxggg yyybbzzz 00000rrr gggbbz00
  178.     lsr.w    #3,d5    ;1 rrrxxggg yyybb0zz 00000000 rrrgggbb
  179.     lsr.w    #3,d6    ;2 rrrxxggg yyybbzzz 00000000 rrrgggbb
  180.     rol.l    d7,d5    ;1 swap
  181.     rol.l    d7,d6    ;2 swap
  182.     lsl.b    #3,d5    ;1 00000000 rrrgggbb rrrxxggg bb0zz000
  183.     lsl.b    #3,d6    ;2 00000000 rrrgggbb rrrxxggg bbzzz000
  184.     lsr.w    #5,d5    ;1 00000000 rrrgggbb 00000rrr xxgggbb0
  185.     lsr.w    #5,d6    ;2 00000000 rrrgggbb 00000rrr xxgggbbz
  186.     lsl.b    #2,d5    ;1 00000000 rrrgggbb 00000rrr gggbb000
  187.     lsl.b    #2,d6    ;2 00000000 rrrgggbb 00000rrr gggbbz00
  188.     lsl.w    #5,d5    ;1 00000000 rrrgggbb rrrgggbb 00000000
  189.     lsl.w    #5,d6    ;2 00000000 rrrgggbb rrrgggbb z0000000
  190.     lsl.l    #8,d5    ;1 rrrgggbb rrrgggbb 00000000 00000000
  191.     lsr.l    #8,d6    ;2 00000000 00000000 rrrgggbb rrrgggbb
  192.     move.l    d5,d4
  193.     or.l    d6,d4    ;  rrrgggbb rrrgggbb rrrgggbb rrrgggbb
  194.  
  195.     subq.w    #1,d3
  196.     bne    .xlop
  197.  
  198.  
  199.     moveq    #0,d5
  200.     moveq    #0,d6
  201.     moveq    #16,d7
  202.  
  203. .xlop    move.w    (a1),d5
  204.     move.w    (2,a1),d6
  205.     move.w    (a6,d5.l),d4    ;  a-
  206.     move.b    (a6,d6.l),d4    ;  ab
  207.     lsl.l    d7,d4        ;ab--
  208.     move.w    (4,a1),d5
  209.     move.w    (6,a1),d6
  210.     move.w    (a6,d5.l),d4    ;abc-
  211.     move.b    (a6,d6.l),d4    ;abcd
  212.     addq.l    #8,a1
  213.     move.l    d4,(a0)+
  214.  
  215.     subq.w    #1,d3
  216.     bne    .xlop
  217. */
  218.  
  219. /* just to be sure */
  220. #if !defined(amigaos)
  221. #  if !defined(__SASC)
  222. #    error AmigaOS required.
  223. #  endif
  224. #endif
  225.  
  226. #define AW_DEBUG 1               /* disable this to get rid of extra debug messages */
  227.  
  228. #define AW_SCALEDEBUG 0          /* help debug (remap)scale routines */
  229.  
  230. #define AW_XPKSUPPORT 1          /* include xpkmaster.library support? */
  231. #define AW_CGXVIDEOSUPPORT 1     /* include cgxvideo.library support? */
  232.  
  233. /* flags for 0x0 specific stuff */
  234. #define AW_USEREMAPSCALE68K 1
  235. #define AW_USEREMAPSCALE68K16 0  /* not implemented yet */
  236. #define AW_USEC2P68K 1
  237. #define AW_USEC2PHAM668K 0       /* not implemented yet */
  238.  
  239. /* if ppc compile make sure it doesn't have any 0x0 parts */
  240. #if defined(AW_PPC)
  241. #  undef AW_USEREMAPSCALE68K
  242. #  undef AW_USEREMAPSCALE68K16
  243. #  undef AW_USEC2P68K
  244. #  undef AW_USEC2PHAM668K
  245. #  define AW_USEREMAPSCALE68K 0
  246. #  define AW_USEREMAPSCALE68K16 0
  247. #  define AW_USEC2P68K 0
  248. #  define AW_USEC2PHAM668K 0
  249. #endif
  250.  
  251. #include <stdio.h>
  252. #include <stdlib.h>
  253. #include <limits.h>
  254. #include <strings.h>
  255.  
  256. #include <exec/exec.h>
  257. #include <dos/dosextens.h>
  258. #include <devices/timer.h>
  259. #include <graphics/gfx.h>
  260. #include <graphics/gfxbase.h>
  261. #include <intuition/intuitionbase.h>
  262. #include <intuition/classusr.h>
  263. #include <intuition/pointerclass.h>
  264. #include <libraries/asl.h>
  265. #include <utility/hooks.h>
  266. #include <cybergraphx/cybergraphics.h>
  267. #if AW_CGXVIDEOSUPPORT
  268. #  include <cybergraphx/cgxvideo.h>
  269. #endif
  270.  
  271. #if defined(AW_PPC)
  272. #  if defined(__SASC)
  273.  
  274. #    include <powerup/ppclib/interface.h>
  275. #    include <powerup/ppclib/time.h>
  276.  
  277. #    include <proto/exec.h>
  278. #    include <proto/timer.h>
  279. #    include <proto/utility.h>
  280. #    include <proto/intuition.h>
  281. #    include <proto/graphics.h>
  282. #    include <proto/dos.h>
  283. #    include <proto/icon.h>
  284. #    include <proto/asl.h>
  285. #    include <powerup/gcclib/powerup_protos.h>
  286. #    include <proto/cybergraphics.h>
  287. #    if AW_CGXVIDEOSUPPORT
  288. #      include <proto/cgxvideo.h>
  289. #    endif
  290. #    if AW_XPKSUPPORT
  291. #      undef AW_XPKSUPPORT
  292. #      define AW_XPKSUPPORT 0  /* not supportted for now */
  293. #    endif
  294. #  else
  295.  
  296. #    include <powerup/ppclib/interface.h>
  297. #    include <powerup/ppclib/time.h>
  298.  
  299. #    include <powerup/ppcinline/exec.h>
  300. #    include <powerup/ppcinline/timer.h>
  301. #    include <powerup/ppcinline/utility.h>
  302. #    include <powerup/ppcinline/intuition.h>
  303. #    include <powerup/ppcinline/graphics.h>
  304. #    include <powerup/ppcinline/dos.h>
  305. #    include <powerup/ppcinline/icon.h>
  306. #    include <powerup/ppcinline/asl.h>
  307. #    include <powerup/gcclib/powerup_protos.h>
  308. #    include <powerup/ppcinline/cybergraphics.h>
  309. #    if AW_CGXVIDEOSUPPORT
  310. #      include <powerup/ppcinline/cgxvideo.h>
  311. #    endif
  312. #    if AW_XPKSUPPORT
  313. #      define NO_XPK_PROTOS
  314. #      define NO_XPK_PRAGMAS
  315. #      include <libraries/xpk.h>
  316. #      include <powerup/ppcinline/xpkmaster.h>
  317. #    endif
  318. #  endif
  319. #else
  320. #  include <proto/exec.h>
  321. #  include <proto/timer.h>
  322. #  include <proto/utility.h>
  323. #  include <proto/intuition.h>
  324. #  include <proto/graphics.h>
  325. #  include <proto/dos.h>
  326. #  include <proto/icon.h>
  327. #  include <proto/asl.h>
  328. #  include <proto/cybergraphics.h>
  329. #  if AW_CGXVIDEOSUPPORT
  330. #    include <proto/cgxvideo.h>
  331. #  endif
  332. #  if AW_XPKSUPPORT
  333. #    if defined(__SASC)
  334. #      include <libraries/xpk.h>
  335. #    else
  336. #      define NO_XPK_PROTOS
  337. #      define NO_XPK_PRAGMAS
  338. #      include <libraries/xpk.h>
  339. #      include <inline/xpkmaster.h>
  340. #    endif
  341. #  endif
  342. #endif
  343.  
  344. #if AW_USEC2P68K
  345. #  include "cpu5azure2.h"
  346. #endif
  347.  
  348. /* gcc 68k only */
  349. #if defined(__GNUC__) && !defined(AW_PPC)
  350. #  include "gccstubs.h"
  351. #endif
  352.  
  353. #if AW_USEREMAPSCALE68K || AW_USEREMAPSCALE68K16
  354. #  include "ddazure2.h"
  355. #endif
  356.  
  357. #include "awin.h"
  358. #if defined(__SASC)
  359. #  include <dos.h>
  360. #else
  361. #  ifndef WBenchMsg
  362. extern struct WBStartup *_WBenchMsg;
  363. #  endif
  364. #endif
  365.  
  366. #define AW_MINWIDTH 64
  367. #define AW_MAXWIDTH 1600
  368. #define AW_MINHEIGHT 48
  369. #define AW_MAXHEIGHT 1280
  370. #define AW_WINRBARW 15
  371. #define AW_PRECISION PRECISION_EXACT
  372. #define AW_SANITY 64
  373.  
  374. #define AW_WWIDCMPFLAGS (IDCMP_RAWKEY|IDCMP_CLOSEWINDOW| \
  375.   IDCMP_SIZEVERIFY|IDCMP_NEWSIZE|IDCMP_INACTIVEWINDOW| \
  376.   IDCMP_ACTIVEWINDOW)
  377.  
  378. #define AW_SWIDCMPFLAGS (IDCMP_RAWKEY| \
  379.   IDCMP_INACTIVEWINDOW|IDCMP_ACTIVEWINDOW)
  380.  
  381. #if defined(AW_PPC) && defined(INVALID_ID)
  382. #  undef INVALID_ID
  383. #  define INVALID_ID (0xffffffffUL)
  384. #endif
  385.  
  386. #if !defined(AW_DEBUG)
  387. #  define AW_DEBUG 0
  388. #endif
  389. #if !defined(AW_SCALEDEBUG)
  390. #  define AW_SCALEDEBUG 0
  391. #endif
  392. #if !defined(AW_USEREMAPSCALE68K)
  393. #  define AW_USEREMAPSCALE68K 0
  394. #endif
  395. #if !defined(AW_USEREMAPSCALE68K16)
  396. #  define AW_USEREMAPSCALE68K16 0
  397. #endif
  398. #if !defined(AW_USEC2P68K)
  399. #  define AW_USEC2P68K 0
  400. #endif
  401. #if !defined(AW_USEC2PHAM668K)
  402. #  define AW_USEC2PHAM668K 0
  403. #endif
  404.  
  405. /* --- code begins here --- */
  406.  
  407. ULONG awsetdebuglevel(struct awdisplay *display,UBYTE level) {
  408.   ULONG oldlevel=0;
  409.   if (display) {
  410.     oldlevel=(ULONG)display->debug;
  411.     display->debug=level;
  412.   }
  413.   AW_DPRINT("awin: AWD_DEBUG on\n");
  414.   if ( (oldlevel>=AWD_DEBUG) &&
  415.        (level<AWD_DEBUG) ) {
  416.     printf("awin: AWD_DEBUG off\n");
  417.   }
  418.   return oldlevel;
  419. }
  420.  
  421. void awivalidatemodeid(struct awdisplay *display,
  422.   ULONG *modeid,ULONG width,ULONG height,ULONG depth) {
  423.  
  424.   ULONG handled=0,flags,maxdepth,mid;
  425.   struct GfxBase *GfxBase;
  426.   struct Library *CyberGfxBase;
  427.  
  428.   /*if (!*modeid) return;*/
  429.  
  430.   if (display) {
  431.     GfxBase=display->GfxBase;
  432.  
  433.     if (*modeid==INVALID_ID) {
  434.       AW_VPRINT("awin: INVALID_ID, falling back to default\n");
  435.       *modeid=0;
  436.     } else if (ModeNotAvailable(*modeid)) {
  437.       AW_VPRINT("awin: modeid not available, falling back to default\n");
  438.       *modeid=0;
  439.     } else {
  440.       if ( (display->CyberGfxBase) && (display->cgfx) ) {
  441.         CyberGfxBase=display->CyberGfxBase;
  442.         if (IsCyberModeID(*modeid)) {
  443.           if (depth==16) {
  444.             if (GetCyberIDAttr(CYBRIDATTR_PIXFMT,*modeid)
  445.               !=PIXFMT_RGB16) {
  446.               AW_VPRINT("awin: modeid not PIXFMT_RGB16, falling back to default\n");
  447.               *modeid=0;
  448.             }
  449.           }
  450.           if (depth==8) {
  451.             if (GetCyberIDAttr(CYBRIDATTR_PIXFMT,*modeid)
  452.               !=PIXFMT_LUT8) {
  453.               AW_VPRINT("awin: modeid not PIXFMT_LUT8, falling back to default\n");
  454.               *modeid=0;
  455.             }
  456.           }
  457.           handled=1;
  458.         }
  459.       }
  460.       if (!handled) {
  461.  
  462.         flags=0;
  463.         awgetpropertyflags(display,*modeid,&flags);
  464.  
  465.         if ( (display->usehamf) &&
  466.              (depth==16) /*&&
  467.              (flags&DIPF_IS_HAM)*/ ) {
  468.  
  469.           /* make 2:1 mode for ham6 */
  470.           mid=BestModeID(
  471.             BIDTAG_SourceID,*modeid,
  472.             BIDTAG_DIPFMustHave,
  473.               (flags&(SPECIAL_FLAGS|DIPF_IS_LACE))|
  474.               (display->nodbuffer?0:DIPF_IS_DBUFFER)|
  475.               DIPF_IS_HAM,
  476.             BIDTAG_NominalWidth,width<=640?width*2:1280,
  477.             BIDTAG_NominalHeight,height,
  478.             BIDTAG_Depth,6,
  479.             TAG_DONE);
  480.  
  481. #if AW_DEBUG
  482.           printf("ham6 modeid: 0x%lx\n",mid);
  483. #endif
  484.  
  485.           if (mid!=INVALID_ID) *modeid=mid;
  486.         }
  487.  
  488.         flags=0;
  489.         awgetpropertyflags(display,*modeid,&flags);
  490.         flags&=SPECIAL_FLAGS;
  491.  
  492.         if (flags) {
  493.           if ( !((display->usehamf) &&
  494.                  (depth==16) &&
  495.                  (flags==DIPF_IS_HAM)) ) {
  496.             AW_VPRINT("awin: modeid has bad attributes, falling back to default\n");
  497.             *modeid=0;
  498.             handled=1;
  499.           }
  500.         }
  501.       }
  502.       if (!handled) {
  503.         maxdepth=0;
  504.         awgetmaxdepth(display,*modeid,&maxdepth);
  505.         if (maxdepth<8) {
  506.           AW_VPRINT("awin: modeid can't handle 8 bits, falling back to default\n");
  507.           *modeid=0;
  508.           handled=1;
  509.         }
  510.       }
  511.       if (!handled) {
  512.         if (BestModeID(
  513.           BIDTAG_SourceID,*modeid,
  514.           BIDTAG_DIPFMustHave,
  515.             (display->nodbuffer?0:DIPF_IS_DBUFFER)|
  516.             ((depth==16)&&display->usehamf?
  517.               DIPF_IS_HAM:0),
  518.           TAG_DONE)==INVALID_ID) {
  519.  
  520.           AW_VPRINT("awin: modeid doesn't have requested attributes, falling back to default\n");
  521.           *modeid=0;
  522.         }
  523.       }
  524.     }
  525.   }  
  526. }
  527.  
  528. void awivalidatedim(struct awdisplay *display,
  529.   ULONG *w,ULONG *h) {
  530.  
  531.   if (display) {
  532.     if (*w<AW_MINWIDTH) *w=AW_MINWIDTH;
  533.     else if (*w>AW_MAXWIDTH) *w=AW_MAXWIDTH;
  534.     if (*h<AW_MINHEIGHT) *h=AW_MINHEIGHT;
  535.     else if (*h>AW_MAXHEIGHT) *h=AW_MAXHEIGHT;
  536.   }
  537. }
  538.  
  539. void awiwbFreeArgs(struct awwbrdargs *rdargs) {
  540.  
  541.   struct ExecBase *SysBase=(*((struct ExecBase **)4));
  542.   struct Library *IconBase;
  543.   struct awwbrdargs* wbrdargs;
  544.  
  545.   if (rdargs) {
  546.     wbrdargs=(struct awwbrdargs*)rdargs;
  547.     IconBase=wbrdargs->IconBase;
  548.  
  549.     if (wbrdargs->type) free(wbrdargs->type);
  550.     if (wbrdargs->name) free(wbrdargs->name);
  551.     if (wbrdargs->dobj) FreeDiskObject(wbrdargs->dobj);
  552.     if (wbrdargs->IconBase) CloseLibrary(wbrdargs->IconBase);
  553.     free(wbrdargs);
  554.   }
  555. }
  556.  
  557. char *awiFindToolType(struct awwbrdargs* wbrdargs,
  558.   char **toolTypeArray,char *typename) {
  559.  
  560.   struct Library *IconBase=wbrdargs->IconBase;
  561.   ULONG tt=0;
  562.   char *s,*d,c,*ret;
  563.   char tmp[128];
  564.  
  565.   while ((s=toolTypeArray[tt++])) {
  566.     d=tmp; ret=NULL;
  567.     while ( (!ret) && (d<tmp+127) ) {
  568.       c=*s++;
  569.       switch (c) {
  570.         case '=': c=0; ret=s; break;
  571.         case 0: ret=s-1; break;
  572.       }
  573.       *d++=c;
  574.     }
  575.     *d=0; /* in case d=tmp+127 ... */
  576.     if (MatchToolValue(typename,tmp)) {
  577.       return ret;
  578.     }
  579.   }
  580.   return NULL;
  581. }
  582.  
  583. struct RDArgs *awiwbReadArgs(struct awdisplay *display,
  584.   const char *template,LONG *array,struct RDArgs *nullargs) {
  585.  
  586.   struct ExecBase *SysBase=(*((struct ExecBase **)4));
  587.   struct Library *DOSBase=display->DOSBase;
  588.   struct Library *IconBase;
  589.   struct awwbrdargs *wbrdargs;
  590.   ULONG len,type;
  591.   char *s,*d,c,fullpath[256];
  592.  
  593.   wbrdargs=malloc(sizeof(struct awwbrdargs));
  594.   if (wbrdargs) {
  595.     memset(wbrdargs,0,sizeof(struct awwbrdargs));
  596.  
  597.     wbrdargs->IconBase=OpenLibrary(ICONNAME,39);
  598.     if (wbrdargs->IconBase) {
  599.  
  600.       IconBase=wbrdargs->IconBase;
  601.  
  602.       NameFromLock(_WBenchMsg->sm_ArgList[0].wa_Lock,fullpath,255);
  603.       AddPart(fullpath,_WBenchMsg->sm_ArgList[0].wa_Name,255);
  604.       fullpath[255]=0;
  605.  
  606.       wbrdargs->dobj=GetDiskObject(fullpath);
  607.       if (wbrdargs->dobj) {
  608.  
  609.         len=strlen(template);
  610.         wbrdargs->tlate=malloc(len+1);
  611.         if (wbrdargs->tlate) {
  612.           s=(char *)template; d=wbrdargs->tlate;
  613.           if (*s) wbrdargs->num=1;
  614.           do {
  615.             c=*s++;
  616.             if (c==',') wbrdargs->num++;
  617.             *d++=c;
  618.           } while (c);
  619.  
  620.       if (wbrdargs->num) {
  621.  
  622.             wbrdargs->type=malloc(sizeof(ULONG)*wbrdargs->num);
  623.             wbrdargs->name=malloc(sizeof(char *)*wbrdargs->num);
  624.             if ( (wbrdargs->name) && (wbrdargs->type) ) {
  625.  
  626.               s=wbrdargs->tlate;
  627.               d=s; len=0; type=0;
  628.               do {
  629.                 c=*s++;
  630.                 switch (c) {
  631.                   case '=':
  632.                     *(s-1)='|';
  633.                     break;
  634.                   case '/':
  635.                     *(s-1)=0;
  636.                     c=*s++;
  637.                     switch (c) {
  638.                       case 'S':
  639.                       case 's': type|=1; type&=~6; break;
  640.                       case 'N':
  641.                       case 'n': type|=2; type&=~5; break;
  642.                       case 'T':
  643.                       case 't': type|=4; type&=~3; break;
  644.                       case 'A':
  645.                       case 'a': type|=8; break;
  646.                       case 'K':
  647.                       case 'k': break;
  648.                       default:
  649.                         AW_VPRINT1("awin: /%c not supported in wbargs!\n",c);
  650.                         awiwbFreeArgs(wbrdargs);
  651.                         SetIoErr(ERROR_BAD_TEMPLATE); return NULL;
  652.                         break;
  653.                     }
  654.                     break;
  655.                   case 0:
  656.                   case ',':
  657.                     wbrdargs->name[len]=d; d=s;
  658.                     wbrdargs->type[len]=type; type=0;
  659.                     *(s-1)=0;
  660.                     len++;
  661.                     break;
  662.                 }
  663.               } while (c);
  664.  
  665.               for (len=0; len<wbrdargs->num; len++) {
  666.                 s=awiFindToolType(wbrdargs,wbrdargs->dobj->do_ToolTypes,
  667.                   wbrdargs->name[len]);
  668.                 if (s) {
  669.                   wbrdargs->type[len]&=~8; /* /A */
  670.  
  671.                   switch (wbrdargs->type[len]) {
  672.                     case 0: /* string */
  673.                       array[len]=(LONG)s;
  674.                       break;
  675.                     case 1: /* /S */
  676.                       if (!*s) {
  677.                         array[len]=1;
  678.                       } else {
  679.                         awiwbFreeArgs(wbrdargs);
  680.                         SetIoErr(ERROR_TOO_MANY_ARGS); return NULL;
  681.                       }
  682.                       break;
  683.                     case 2: /* /N */
  684.                       if (*s) {
  685.                         ((ULONG *)wbrdargs->name)[len]=strtol(s,&d,10);
  686.                         if (*d) {
  687.                           awiwbFreeArgs(wbrdargs);
  688.                           SetIoErr(ERROR_BAD_NUMBER); return NULL;
  689.                         }
  690.                         array[len]=(LONG)&(((ULONG *)wbrdargs->name)[len]);
  691.                       } else {
  692.                         awiwbFreeArgs(wbrdargs);
  693.                         SetIoErr(ERROR_KEY_NEEDS_ARG); return NULL;
  694.                       }
  695.                       break;
  696.                     case 4: /* /T */
  697.                       if (MatchToolValue("yes|on|1",s)) {
  698.                         array[len]=1;
  699.                       } else if (MatchToolValue("no|off|0",s)) {
  700.                         array[len]=0;
  701.                       } else {
  702.                         awiwbFreeArgs(wbrdargs);
  703.                         SetIoErr(ERROR_KEY_NEEDS_ARG); return NULL;
  704.                       }
  705.                       break;
  706.                   }
  707.                 }
  708.               }
  709.               for (len=0; len<wbrdargs->num; len++) {
  710.                 if (wbrdargs->type[len]&8) {
  711.                   awiwbFreeArgs(wbrdargs);
  712.                   SetIoErr(ERROR_REQUIRED_ARG_MISSING); return NULL;
  713.                 }
  714.               }
  715.  
  716.               /* success, template, array set */
  717.               return (struct RDArgs *)wbrdargs;
  718.             } else {
  719.               awiwbFreeArgs(wbrdargs);
  720.               SetIoErr(ERROR_NO_FREE_STORE); return NULL;
  721.             }
  722.           } else {
  723.  
  724.             /* success, no template, array not set */
  725.             return (struct RDArgs *)wbrdargs;
  726.           }
  727.         } else {
  728.           awiwbFreeArgs(wbrdargs);
  729.           SetIoErr(ERROR_NO_FREE_STORE); return NULL;
  730.         }
  731.       } else {
  732.         awiwbFreeArgs(wbrdargs);
  733.         /* SetIoErr() by GetDiskObject */
  734.         return NULL;
  735.       }
  736.     } else {
  737.       awiwbFreeArgs(wbrdargs);
  738.       SetIoErr(ERROR_INVALID_RESIDENT_LIBRARY); return NULL;
  739.     }
  740.   }
  741.   SetIoErr(ERROR_NO_FREE_STORE); return NULL;
  742. }
  743.  
  744. struct awrdargs *awreadargs(struct awdisplay *display,
  745.   struct awodargs *odargs,const char *template, LONG *array) {
  746.  
  747.   struct awrdargs *args;
  748.  
  749.   typedef enum awmyargs {
  750.     AW_AWINDOW=0,
  751.     AW_ASCREEN,
  752.     AW_AMODEID8,
  753.     AW_AMODEID16,
  754.     AW_AREQMODE8,
  755.     AW_AREQMODE16,
  756.     AW_APUBSCREEN,
  757.     AW_AWIDTH,
  758.     AW_AHEIGHT,
  759.     AW_AUINA,
  760.     AW_ADBUFFER,
  761.     AW_AWAITSWAP,
  762.     AW_ANATIVE,
  763.     AW_AHAM,
  764.     AW_ADIRECTDRAW,
  765.     AW_ACGXV,
  766.     AW_AUSEARGB16,
  767.     AW_ANUM
  768.   } awmyargs;
  769.  
  770.   const char *itemplate=
  771.     "WINDOW/S,"
  772.     "SCREEN/S,"
  773.     "SCREENMODE8=MODEID8=MODEID/K,"
  774.     "SCREENMODE16=MODEID16/K,"
  775.     "REQUESTMODE8=REQMODE8=MODEREQ8/S,"
  776.     "REQUESTMODE16=REQMODE16=MODEREQ16/S,"
  777.     "PUBSCREEN=PUB/K,"
  778.     "WIDTH=WID=W/N/K,"
  779.     "HEIGHT=HEI=H/N/K,"
  780.     "UPDATEINACTIVE=UINA/T,"
  781.     "DOUBLEBUFFER=DBUFFER/T,"
  782.     "WAITSWAP/T,"
  783.     "FORCENATIVE=NATIVE/T,"
  784.     "USEHAM=HAM/T,"
  785.     "DIRECTDRAW/T,"
  786.     "USECGXVIDEO=CGXV/T,"
  787.     "USEARGB16/T,";  /* last ',' is handled */
  788.  
  789.   const char *tpt;
  790.   char *temp=NULL,ioebuf[80];
  791.   ULONG x,nargs=0,oldflags,olddepth;
  792.   struct Library *DOSBase=display->DOSBase;
  793.  
  794.   args=malloc(sizeof(struct awrdargs));
  795.   if (args) {
  796.     memset(args,0,sizeof(struct awrdargs));
  797.     args->DOSBase=DOSBase;
  798.  
  799.     if ( (template) && (*template) && (array) ) {
  800.  
  801.       for (tpt=template,nargs=1+AW_ANUM; *tpt; tpt++)
  802.         if (*tpt==',') nargs++;
  803.  
  804. #if AW_DEBUG
  805. /*
  806.       printf(": total %lu arguments\n",nargs);
  807. */
  808. #endif
  809.  
  810.       args->array=malloc(sizeof(LONG)*nargs);
  811.       if (args->array) {
  812.         /* clear our argarray... */
  813.         memset(args->array,0,sizeof(LONG)*AW_ANUM);
  814.         /* and copy user argarray after em */
  815.         memcpy(&args->array[AW_ANUM],array,
  816.           sizeof(LONG)*(nargs-AW_ANUM));
  817.  
  818.         temp=malloc(strlen(itemplate)+strlen(template)+1);
  819.  
  820.       } else {
  821.         awfreeargs(args); args=NULL;
  822.       }
  823.     } else {
  824.       args->array=malloc(sizeof(LONG)*AW_ANUM);
  825.       if (args->array) {
  826.         /* clear our argarray... */
  827.         memset(args->array,0,sizeof(LONG)*AW_ANUM);
  828.  
  829.         temp=malloc(strlen(itemplate)+1);
  830.  
  831.       } else {
  832.         awfreeargs(args); args=NULL;
  833.       }
  834.     }
  835.  
  836.     if (args) {
  837.       if (temp) {
  838.  
  839.         /* fill our argarray toggles (/T) from odargs */
  840.  
  841.         args->array[AW_AUINA]=odargs->flags&AWODAF_DONTUPDATEINA?0:1;
  842.         args->array[AW_ADBUFFER]=odargs->flags&AWODAF_NODBUFFER?0:1;
  843.         args->array[AW_ANATIVE]=odargs->flags&AWODAF_FORCENATIVE?1:0;
  844.         args->array[AW_AHAM]=odargs->flags&AWODAF_USEHAM?1:0;
  845.         args->array[AW_ADIRECTDRAW]=odargs->flags&AWODAF_DIRECTDRAW?1:0;
  846.         args->array[AW_AWAITSWAP]=odargs->flags&AWODAF_WAITSWAP?1:0;
  847.         args->array[AW_ACGXV]=odargs->flags&AWODAF_USECGXVIDEO?1:0;
  848.         args->array[AW_AUSEARGB16]=odargs->flags&AWODAF_USEARGB16?1:0;
  849.  
  850.  
  851.         /* create full template */
  852.         strcpy(temp,itemplate);
  853.         if (nargs) {
  854.           strcat(temp,template);
  855.         } else {
  856.           /* handle last ',' */
  857.           temp[strlen(temp)-1]=0;
  858.         }
  859.  
  860. #if AW_DEBUG
  861. /*
  862.         printf(": full template: \"%s\"\n",temp);
  863. */
  864. #endif
  865.  
  866.         if (_WBenchMsg) {
  867.           args->rda=awiwbReadArgs(display,temp,args->array,NULL);
  868.           args->wb=1;
  869.         } else {
  870.           args->rda=ReadArgs(temp,args->array,NULL);
  871.         }
  872.  
  873.         free(temp);
  874.  
  875.         if (args->rda) {
  876.  
  877.           if (nargs) {
  878.             /* copy user argarray back... */
  879.             memcpy(array,&args->array[AW_ANUM],
  880.               sizeof(LONG)*(nargs-AW_ANUM));
  881.           }
  882.  
  883.           /* handle our arguments */
  884.  
  885.           /* check mutually exclusive args */
  886.  
  887.           if ( (args->array[AW_AWINDOW] && args->array[AW_ASCREEN]) ||
  888.                (args->array[AW_APUBSCREEN] && args->array[AW_ASCREEN]) ||
  889.                (args->array[AW_ANATIVE] && args->array[AW_ADIRECTDRAW]) ) {
  890.             if (args->array[AW_ANATIVE]) {
  891.               /* NATIVE overrides DIRECTDRAW */
  892.               args->array[AW_ADIRECTDRAW]=0;
  893.             } else {
  894.               /* WINDOW or PUBSCREEN overrides SCREEN */
  895.               args->array[AW_ASCREEN]=0;
  896.             }
  897.             AW_VPRINT("awin: mutually exclusive arguments removed\n");
  898.           }
  899.  
  900.           /* set odargs fields... */
  901.  
  902.           odargs->flags|=args->array[AW_AWINDOW]?AWODAF_INITWINDOW:0;
  903.           odargs->flags&=args->array[AW_ASCREEN]?(~AWODAF_INITWINDOW):(~0);
  904.  
  905.           if (args->array[AW_AMODEID8]) {
  906.             x=0;
  907.             if (sscanf((char *)args->array[AW_AMODEID8],"0x%lx",&x)==1)
  908.               odargs->modeid8=x;
  909.             else if (sscanf((char *)args->array[AW_AMODEID8],"0X%lx",&x)==1)
  910.               odargs->modeid8=x;
  911.             else if (sscanf((char *)args->array[AW_AMODEID8],"$%lx",&x)==1)
  912.               odargs->modeid8=x;
  913.             else if (sscanf((char *)args->array[AW_AMODEID8],"%lu",&x)==1)
  914.               odargs->modeid8=x;
  915.             else AW_VPRINT("awin: bad modeid number\n");
  916.           }
  917.  
  918.           if (args->array[AW_AMODEID16]) {
  919.             x=0;
  920.             if (sscanf((char *)args->array[AW_AMODEID16],"0x%lx",&x)==1)
  921.               odargs->modeid16=x;
  922.             else if (sscanf((char *)args->array[AW_AMODEID16],"0X%lx",&x)==1)
  923.               odargs->modeid16=x;
  924.             else if (sscanf((char *)args->array[AW_AMODEID16],"$%lx",&x)==1)
  925.               odargs->modeid16=x;
  926.             else if (sscanf((char *)args->array[AW_AMODEID16],"%lu",&x)==1)
  927.               odargs->modeid16=x;
  928.             else AW_VPRINT("awin: bad modeid number\n");
  929.           }
  930.  
  931.           if (args->array[AW_APUBSCREEN]) {
  932.             temp=malloc(
  933.               strlen((char *)args->array[AW_APUBSCREEN])+1);
  934.             if (temp) {
  935.               /* will keep this memory until program is quit */
  936.               strcpy(temp,(char *)args->array[AW_APUBSCREEN]);
  937.               odargs->pubscreen=temp;
  938.             }
  939.           }
  940.  
  941.           if (args->array[AW_AWIDTH])
  942.             odargs->width=*((ULONG *)args->array[AW_AWIDTH]);
  943.  
  944.           if (args->array[AW_AHEIGHT])
  945.             odargs->height=*((ULONG *)args->array[AW_AHEIGHT]);
  946.  
  947.           /* update flags */
  948.  
  949.           odargs->flags=( odargs->flags&~(
  950.             AWODAF_DONTUPDATEINA|
  951.             AWODAF_NODBUFFER|
  952.             AWODAF_FORCENATIVE|
  953.             AWODAF_USEHAM|
  954.             AWODAF_DIRECTDRAW|
  955.             AWODAF_WAITSWAP|
  956.             AWODAF_USECGXVIDEO) ) /* !! */
  957.  
  958.             | (
  959.             (args->array[AW_AUINA]?       0:AWODAF_DONTUPDATEINA)|
  960.             (args->array[AW_ADBUFFER]?    0:AWODAF_NODBUFFER)|
  961.             (args->array[AW_ANATIVE]?     AWODAF_FORCENATIVE:0)|
  962.             (args->array[AW_AHAM]?        AWODAF_USEHAM:0)|
  963.             (args->array[AW_ADIRECTDRAW]? AWODAF_DIRECTDRAW:0)|
  964.             (args->array[AW_AWAITSWAP]?   AWODAF_WAITSWAP:0)|
  965.             (args->array[AW_ACGXV]?       AWODAF_USECGXVIDEO:0)|
  966.             (args->array[AW_AUSEARGB16]?  AWODAF_USEARGB16:0)); /* !! */
  967.  
  968.           /* and if AREQMODEn put up an screenmodereq */
  969.  
  970.           oldflags=awsetflags(display,odargs->flags);
  971.           olddepth=display->srcdepth;
  972.           if (args->array[AW_AREQMODE8]) {
  973.             display->srcdepth=8;
  974.             (void)awscreenmodereq(
  975.               display,
  976.               &odargs->modeid8,8,
  977.               &odargs->width,
  978.               &odargs->height,
  979.               1);
  980.           }
  981.           if (args->array[AW_AREQMODE16]) {
  982.             display->srcdepth=16;
  983.             (void)awscreenmodereq(
  984.               display,
  985.               &odargs->modeid16,16,
  986.               &odargs->width,
  987.               &odargs->height,
  988.               1);
  989.           }
  990.           display->srcdepth=olddepth;
  991.           awsetflags(display,oldflags);
  992.  
  993.           free(args->array); args->array=NULL;
  994.  
  995.           /* return ok */
  996.           return args;
  997.  
  998.         } else {
  999.           if (display->debug>=AWD_VERBOSE) {
  1000.             if (Fault(IoErr(),"",ioebuf,80))
  1001.               printf("awin%s\n",ioebuf);
  1002.           }
  1003.           awfreeargs(args);
  1004.         }
  1005.  
  1006.       } else {
  1007.         awfreeargs(args);
  1008.       }
  1009.     }
  1010.  
  1011.   }
  1012.   return NULL;
  1013. }
  1014.  
  1015. void awfreeargs(struct awrdargs *args) {
  1016.   struct Library *DOSBase=args->DOSBase;
  1017.  
  1018.   if (args) {
  1019.     if (args->rda) {
  1020.       if (args->wb) awiwbFreeArgs((struct awwbrdargs *)args->rda);
  1021.       else FreeArgs(args->rda);
  1022.     }
  1023.     if (args->array) free(args->array);
  1024.  
  1025.     free(args);
  1026.   }
  1027. }
  1028.  
  1029. #if defined(AW_PPC)
  1030. #  define AW_ISMRHOOKF 0
  1031. #else
  1032. #  define AW_ISMRHOOKF 1
  1033. #endif
  1034.  
  1035. #if AW_ISMRHOOKF
  1036. #  ifdef __SASC
  1037. ULONG __asm __saveds awismrFilterFunc_hookentry(
  1038.   register __a0 struct Hook *hook,
  1039.   register __a1 ULONG modeid,
  1040.   register __a2 struct ScreenModeRequester *srm);
  1041. #  else
  1042. #    ifdef __GNUC__
  1043. ULONG __saveds awismrFilterFunc_hookentry(
  1044.   struct Hook *hook __asm("a0"),
  1045.   ULONG modeid __asm("a1"),
  1046.   struct ScreenModeRequester *srm __asm("a2"));
  1047. #    else
  1048. #      error awismrFilterFunc_hookentry prototype
  1049. #    endif
  1050. #  endif
  1051.  
  1052. #  ifdef __SASC
  1053. ULONG __asm __saveds awismrFilterFunc_hookentry(
  1054.   register __a0 struct Hook *hook,
  1055.   register __a1 ULONG modeid,
  1056.   register __a2 struct ScreenModeRequester *srm) {
  1057. #  else
  1058. #    ifdef __GNUC__
  1059. ULONG __saveds awismrFilterFunc_hookentry(
  1060.   struct Hook *hook __asm("a0"),
  1061.   ULONG modeid __asm("a1"),
  1062.   struct ScreenModeRequester *srm __asm("a2")) {
  1063. #    else
  1064. #      error awismrFilterFunc_hookentry function
  1065. #    endif
  1066. #  endif
  1067.   struct awdisplay *display=(struct awdisplay *)(srm->sm_UserData);
  1068.   ULONG xa,ya;
  1069.   float rat;
  1070.   struct Library *CyberGfxBase;
  1071.  
  1072.   if (display) {
  1073.     if (awgetaspectratio(display,modeid,&xa,&ya)) {
  1074.       rat=((float)xa)/ya;
  1075.  
  1076.       /* don't allow weird aspect ratios */
  1077.       if ( (rat<.666) || (rat>1.50) ) {
  1078.         return 0L;
  1079.       }
  1080.     }
  1081.     if ( (display->CyberGfxBase) && (display->cgfx) ) {
  1082.       CyberGfxBase=display->CyberGfxBase;
  1083.       if (IsCyberModeID(modeid)) {
  1084.         switch (GetCyberIDAttr(CYBRIDATTR_PIXFMT,modeid)) {
  1085.           case PIXFMT_LUT8:   /* only allow LUT8 and RGB16 */
  1086.           case PIXFMT_RGB16:
  1087.             break;
  1088.           default: return 0L;
  1089.         }
  1090.       }
  1091.     }
  1092.   }
  1093.   return 1L;
  1094. }
  1095. #endif /* AW_ISMRHOOKF */
  1096.  
  1097. ULONG awscreenmodereq(struct awdisplay *display,ULONG *modeid,
  1098.   ULONG depth,ULONG *w,ULONG *h,ULONG dodim) {
  1099.  
  1100.   struct ExecBase *SysBase;
  1101.   struct IntuitionBase *IntuitionBase;
  1102.   struct Library *AslBase;
  1103.   struct ScreenModeRequester *smr;
  1104.   struct Hook hook;
  1105.   /*struct Process *thisproc=FindTask(NULL);*/
  1106.   ULONG ret=0,propertyflags=0;
  1107.  
  1108.   if (display) {
  1109.     SysBase=display->SysBase;
  1110.     IntuitionBase=display->IntuitionBase;
  1111.  
  1112.     AslBase=OpenLibrary("asl.library",38L);
  1113.     if (AslBase) {
  1114.  
  1115. #if AW_ISMRHOOKF
  1116.       /* Initialize the hook for awismrFilterFunc_hookentry() */
  1117.       hook.h_Entry   =(unsigned long (* )())awismrFilterFunc_hookentry;
  1118.       hook.h_SubEntry=0;   /* this program does not use this */
  1119.       hook.h_Data    =0;   /* this program does not use this */
  1120. #endif
  1121.  
  1122.       /* should test usehamf && depth==16 ? */
  1123.       if (display->doham) {
  1124.         propertyflags|=DIPF_IS_HAM;
  1125.       }
  1126.  
  1127.       smr=(struct ScreenModeRequester *)
  1128.         AllocAslRequestTags(ASL_ScreenModeRequest,
  1129.           /*ASLSM_Window,(ULONG)thisproc->pr_WindowPtr,*/
  1130.           ASLSM_SleepWindow,1,
  1131.  
  1132.           *modeid?ASLSM_InitialDisplayID:TAG_IGNORE,*modeid,
  1133.           *w?ASLSM_InitialDisplayWidth:TAG_IGNORE,*w,
  1134.           *h?ASLSM_InitialDisplayHeight:TAG_IGNORE,*h,
  1135.  
  1136.           /*dodim?ASLSM_InitialOverscanType:TAG_IGNORE,OSCAN_TEXT,*/
  1137.  
  1138.           ASLSM_PropertyMask,
  1139.             DIPF_IS_DUALPF|DIPF_IS_PF2PRI|DIPF_IS_HAM|
  1140.             DIPF_IS_EXTRAHALFBRITE|
  1141.             propertyflags,
  1142.  
  1143.           ASLSM_PropertyFlags,
  1144.             propertyflags,
  1145.  
  1146.           dodim?ASLSM_DoWidth:TAG_IGNORE,1,
  1147.           dodim?ASLSM_DoHeight:TAG_IGNORE,1,
  1148.           /*dodim?ASLSM_DoOverscanType:TAG_IGNORE,1,*/
  1149.  
  1150.           ASLSM_MinWidth,AW_MINWIDTH,
  1151.           ASLSM_MinHeight,AW_MINHEIGHT,
  1152.           ASLSM_MaxWidth,AW_MAXWIDTH,
  1153.           ASLSM_MaxHeight,AW_MAXHEIGHT,
  1154.  
  1155.           ASLSM_InitialDisplayDepth,depth,
  1156.           ASLSM_MinDepth,6,
  1157.           ASLSM_MaxDepth,depth,
  1158.  
  1159.           AW_ISMRHOOKF?ASLSM_FilterFunc:TAG_IGNORE,(ULONG)&hook,
  1160.           ASLSM_UserData,(ULONG)display,
  1161.  
  1162.           TAG_DONE);
  1163.  
  1164.       if (smr) {
  1165.  
  1166.         /* Pop up the requester */
  1167.         if (AslRequest(smr, NULL)) {
  1168.  
  1169.           ret=1;
  1170.           *modeid=smr->sm_DisplayID;
  1171.           *w=smr->sm_DisplayWidth;
  1172.           *h=smr->sm_DisplayHeight;
  1173.  
  1174.           awivalidatedim(display,w,h);
  1175.           awivalidatemodeid(display,modeid,*w,*h,depth);
  1176. #if 0
  1177.           printf("display mode id: 0x%lx\n"
  1178.             "width: %ld\nheight: %ld\n"
  1179.             "depth: %ld\noscan: %ld\n"
  1180.             "bitmapwidth: %ld\nbitmapheight: %ld\n",
  1181.             smr->sm_DisplayID,
  1182.             smr->sm_DisplayWidth,
  1183.             smr->sm_DisplayHeight,
  1184.             smr->sm_DisplayDepth,
  1185.             smr->sm_OverscanType,
  1186.             smr->sm_BitMapWidth,
  1187.             smr->sm_BitMapHeight);
  1188. #endif
  1189.         }
  1190.  
  1191.         FreeAslRequest(smr);
  1192.       } else {
  1193.         AW_VPRINT("awin: AllocAslRequestTags failed\n");
  1194.       }
  1195.  
  1196.       CloseLibrary(AslBase);
  1197.     } else {
  1198.       /* asl.library not found, beep as error */
  1199.       DisplayBeep(display->screen);
  1200.     }
  1201.   }
  1202.   return ret;
  1203. }
  1204.  
  1205. /* timer API */
  1206.  
  1207. struct awtimer *awcreatetimer(struct awdisplay *display) {
  1208. #if defined(AW_PPC)
  1209.   struct awtimer *timer;
  1210.   struct TagItem tags[2];
  1211.  
  1212.   if (display) {
  1213.     timer=malloc(sizeof(struct awtimer));
  1214.     if (timer) {
  1215.       memset(timer,0,sizeof(struct awtimer));
  1216.  
  1217.       tags[0].ti_Tag=PPCTIMERTAG_CPU; tags[0].ti_Data=1;
  1218.       tags[1].ti_Tag=TAG_DONE;
  1219.       timer->timerobject=PPCCreateTimerObject(tags);
  1220.       if (timer->timerobject) {
  1221.  
  1222.         ppcgettimerobject(timer->timerobject,
  1223.           PPCTIMERTAG_TICKSPERSEC,timer->tickspersec);
  1224.         ppcgettimerobject(timer->timerobject,
  1225.           PPCTIMERTAG_CURRENTTICKS,timer->start);
  1226.  
  1227.         return timer;
  1228.       }
  1229.       awdeletetimer(timer);
  1230.     }
  1231.   }
  1232.   return NULL;
  1233. }
  1234. #else
  1235.   struct awtimer *timer;
  1236.   struct Library *TimerBase;
  1237.  
  1238.   if (display) {
  1239.     TimerBase=display->TimerBase;
  1240.  
  1241.     timer=malloc(sizeof(struct awtimer));
  1242.     if (timer) {
  1243.       memset(timer,0,sizeof(struct awtimer));
  1244.  
  1245.       timer->timerbase=display->TimerBase;
  1246.       timer->tickspersec=ReadEClock(&timer->start);
  1247.       return timer;
  1248.     }
  1249.   }
  1250.   return NULL;
  1251. }
  1252. #endif
  1253.  
  1254. void awrestarttimer(struct awtimer *timer) {
  1255. #if defined(AW_PPC)
  1256.   if (timer) {
  1257.     ppcgettimerobject(timer->timerobject,PPCTIMERTAG_CURRENTTICKS,timer->start);
  1258.   }
  1259. }
  1260. #else
  1261.   struct Library *TimerBase;
  1262.  
  1263.   if (timer) {
  1264.     TimerBase=timer->timerbase;
  1265.     ReadEClock(&timer->start);
  1266.   }
  1267. }
  1268. #endif
  1269.  
  1270. /* return milliseconds elapsed since awcreatetimer/awrestarttimer */
  1271. ULONG awreadtimer(struct awtimer *timer) {
  1272. #if defined(AW_PPC)
  1273.  
  1274.   /* this routine wraps in 4*1024*1024*1024/1000=4294964 seconds */
  1275.  
  1276.  
  1277.   ULONG start[2],current[2];
  1278.  
  1279.   if (timer) {
  1280.     start[0]=timer->start[0]; start[1]=timer->start[1];
  1281.     ppcgettimerobject(timer->timerobject,PPCTIMERTAG_CURRENTTICKS,current);
  1282.  
  1283.     /* PPCSub64:
  1284.  
  1285.     1c 00011f79 - 1b 40eede5c = 1 bf12411d ???
  1286.     doesn't handle overflow of lower long correctly!
  1287.  
  1288.     printf("%lx %08lx - %lx %08lx = ",
  1289.       current[0],current[1],start[0],start[1]);
  1290.     start[0]=current[0]-start[0]-(current[1]<start[1]?1:0);
  1291.     start[1]=current[1]-start[1];
  1292.     printf("%lx %08lx\n",start[0],start[1]);
  1293.     */
  1294.  
  1295.     sub64p(start,current);
  1296.  
  1297.     current[0]=0; current[1]=1000;
  1298.     ppcmulu64p(start,current);
  1299.     ppcdivu64p(start,timer->tickspersec);
  1300.     /* start[0] should be 0 */
  1301.     return start[1];
  1302.   }
  1303.   return 0L;
  1304. }
  1305. #else
  1306.   struct Library *TimerBase;
  1307.   struct EClockVal current;
  1308.  
  1309.   if (timer) {
  1310.     TimerBase=timer->timerbase;
  1311.     ReadEClock(¤t);
  1312.     SubTime((struct timeval *)¤t,(struct timeval *)&timer->start);
  1313.     return (ULONG)(1000.0*current.ev_lo/((double)timer->tickspersec));
  1314.   }
  1315.   return 0L;
  1316. }
  1317. #endif
  1318.  
  1319. /* return microseconds elapsed since awcreatetimer/awrestarttimer */
  1320. ULONG awreadtimer_us(struct awtimer *timer) {
  1321. #if defined(AW_PPC)
  1322.  
  1323.   /* this routine wraps in 4*1024*1024*1024/1000000=4292 seconds */
  1324.  
  1325.   ULONG start[2],current[2];
  1326.  
  1327.   if (timer) {
  1328.     start[0]=timer->start[0]; start[1]=timer->start[1];
  1329.     ppcgettimerobject(timer->timerobject,PPCTIMERTAG_CURRENTTICKS,current);
  1330.     sub64p(start,current);
  1331.     current[0]=0; current[1]=1000000;
  1332.     ppcmulu64p(start,current);
  1333.     ppcdivu64p(start,timer->tickspersec);
  1334.     /* start[0] should be 0 */
  1335.     return start[1];
  1336.   }
  1337.   return 0L;
  1338. }
  1339. #else
  1340.   struct Library *TimerBase;
  1341.   struct EClockVal current;
  1342.  
  1343.   if (timer) {
  1344.     TimerBase=timer->timerbase;
  1345.     ReadEClock(¤t);
  1346.     SubTime((struct timeval *)¤t,(struct timeval *)&timer->start);
  1347.     return 10UL*current.ev_lo/((timer->tickspersec+50000UL)/100000UL);
  1348.   }
  1349.   return 0L;
  1350. }
  1351. #endif
  1352.  
  1353. void awdeletetimer(struct awtimer *timer) {
  1354.   if (timer) {
  1355. #if defined(AW_PPC)
  1356.     if (timer->timerobject) PPCDeleteTimerObject(timer->timerobject);
  1357. #endif
  1358.  
  1359.     free(timer);
  1360.   }
  1361. }
  1362.  
  1363.  
  1364. ULONG awtoinnerw(struct awdisplay *display, ULONG width) {
  1365.   if (display->window)
  1366.     return width - display->window->BorderLeft - display->window->BorderRight;
  1367.   else if (display->screen)
  1368.     return width - display->screen->WBorLeft - display->screen->WBorRight
  1369.       - AW_WINRBARW;
  1370.   else return width;
  1371. }
  1372. ULONG awtowindoww(struct awdisplay *display, ULONG width) {
  1373.   if (display->window)
  1374.     return width + display->window->BorderLeft + display->window->BorderRight;
  1375.   if (display->screen)
  1376.     return width + display->screen->WBorLeft + display->screen->WBorRight
  1377.       + AW_WINRBARW;
  1378.   else return width;
  1379. }
  1380. ULONG awtoinnerh(struct awdisplay *display, ULONG height) {
  1381.   if (display->window)
  1382.     return height - display->window->BorderTop - display->window->BorderBottom;
  1383.   if (display->screen)
  1384.     return height - display->screen->WBorTop - display->screen->WBorBottom
  1385.       - display->screen->Font->ta_YSize - 1;
  1386.   else return height;
  1387. }
  1388. ULONG awtowindowh(struct awdisplay *display, ULONG height) {
  1389.   if (display->window)
  1390.     return height + display->window->BorderTop + display->window->BorderBottom;
  1391.   if (display->screen)
  1392.     return height + display->screen->WBorTop + display->screen->WBorBottom
  1393.       + display->screen->Font->ta_YSize + 1;
  1394.   else return height;
  1395. }
  1396.  
  1397. AWIDCMPHOOK_PTR awsetidcmphook(struct awdisplay *display,
  1398.   AWIDCMPHOOK_PTR idcmphook) {
  1399.  
  1400.   AWIDCMPHOOK_PTR oldhook;
  1401.   oldhook=display->idcmphook;
  1402.   display->idcmphook=idcmphook;
  1403.   return oldhook;
  1404. }
  1405.  
  1406. ULONG awsetidcmpflags(struct awdisplay *display,
  1407.   ULONG idcmpflags) {
  1408.  
  1409.   struct IntuitionBase *IntuitionBase=display->IntuitionBase;
  1410.   ULONG oldflags,flagmask;
  1411.  
  1412.   if (display->window) {
  1413.     if (display->windowmode) flagmask=AW_WWIDCMPFLAGS;
  1414.       else flagmask=AW_SWIDCMPFLAGS;
  1415.  
  1416.     if ( (display->window->IDCMPFlags)!=
  1417.          (flagmask|idcmpflags) ) {
  1418.       ModifyIDCMP(display->window,flagmask|idcmpflags);
  1419.     }
  1420.   }
  1421.  
  1422.   oldflags=display->idcmpflags;
  1423.   display->idcmpflags=idcmpflags;
  1424.   return oldflags;
  1425. }
  1426.  
  1427. struct BitMap *awallocbm(ULONG x,ULONG y,ULONG d,ULONG f,struct BitMap *b,
  1428.   ULONG fblit) {
  1429.  
  1430.   struct Library *GfxBase;
  1431.   struct Library *DOSBase;
  1432.   struct Process *proc;
  1433.   struct BitMap *bm=NULL;
  1434.   char *oname=NULL,opn[256];
  1435.   struct ExecBase *SysBase=(*((struct ExecBase **)4));
  1436.  
  1437. #if defined(AW_PPC)
  1438.   struct Caos kaaos;
  1439.  
  1440.   /* -*- odump by Harry "Piru" Sintonen */
  1441.   static const ULONG awsetlnnameinner[]={
  1442.     0x20894e75};
  1443.   /* -*- */
  1444. #endif
  1445.  
  1446.   GfxBase=OpenLibrary(GRAPHICSNAME,39);
  1447.   if (GfxBase) {
  1448.  
  1449.     if (fblit) {
  1450.       DOSBase=OpenLibrary("dos.library",39);
  1451.       proc=(struct Process *)FindTask(NULL);
  1452.       Forbid();
  1453.       if ( (DOSBase) && (proc->pr_Task.tc_Node.ln_Type==NT_PROCESS) &&
  1454.            (proc->pr_CLI) ) {
  1455.         GetProgramName(opn,255);
  1456.         SetProgramName("FBLITPLANES");
  1457.       } else {
  1458.         oname=proc->pr_Task.tc_Node.ln_Name;
  1459.  
  1460. #if defined(AW_PPC)
  1461.         kaaos.a0=(ULONG)&proc->pr_Task.tc_Node.ln_Name;
  1462.         kaaos.a1=(ULONG)"FBLITPLANES";
  1463.         kaaos.caos_Un.Function=(APTR)awsetlnnameinner;
  1464.         kaaos.M68kCacheMode=IF_CACHEFLUSHALL;
  1465.         kaaos.PPCCacheMode=IF_CACHEFLUSHALL;
  1466.         PPCCallM68k(&kaaos);
  1467. #else
  1468.         proc->pr_Task.tc_Node.ln_Name="FBLITPLANES";
  1469. #endif
  1470.  
  1471.       }
  1472.  
  1473.       bm=AllocBitMap(x,y,d,f,b);
  1474.       
  1475.       if ( (DOSBase) && (proc->pr_Task.tc_Node.ln_Type==NT_PROCESS) &&
  1476.            (proc->pr_CLI) ) {
  1477.         SetProgramName(opn);
  1478.       } else {
  1479.  
  1480. #if defined(AW_PPC)
  1481.         kaaos.a0=(ULONG)&proc->pr_Task.tc_Node.ln_Name;
  1482.         kaaos.a1=(ULONG)oname;
  1483.         kaaos.caos_Un.Function=(APTR)awsetlnnameinner;
  1484.         kaaos.M68kCacheMode=IF_CACHEFLUSHALL;
  1485.         kaaos.PPCCacheMode=IF_CACHEFLUSHALL;
  1486.         PPCCallM68k(&kaaos);
  1487. #else
  1488.         proc->pr_Task.tc_Node.ln_Name=oname;
  1489. #endif
  1490.  
  1491.       }
  1492.       Permit();
  1493.       CloseLibrary(DOSBase);
  1494.     } else {
  1495.  
  1496.       bm=AllocBitMap(x,y,d,f,b);
  1497.     }
  1498.  
  1499.     CloseLibrary(GfxBase);
  1500.   }
  1501.   return bm;
  1502. }
  1503.  
  1504. void awinitc2p(struct awdisplay *display) {
  1505.  
  1506.   /* c2p specific init */
  1507.  
  1508. #if AW_USEC2P68K
  1509.  
  1510.   awinitchunky2planar(
  1511.     display->framebuffer,
  1512.     display->scrwidth,
  1513.     display->height,
  1514.     display->dstdepth);
  1515. #endif
  1516. }
  1517.  
  1518. void awdoc2p(struct awdisplay *display) {
  1519.  
  1520.   /* c2p specific stuff */
  1521.  
  1522. #if AW_USEC2P68K
  1523.  
  1524.   awchunky2planar(display->c2pbitmap[display->curbuffer].Planes[0]);
  1525.  
  1526. #else
  1527.  
  1528. /* based on c2p from QMap
  1529. */
  1530.  
  1531. #define m3 0x33333333
  1532. #define m5 0x55555555
  1533. #define mf1 0x00ff00ff
  1534. #define mf2 0x0f0f0f0f
  1535.  
  1536.   unsigned long planesize32=display->scrwidth*display->height/32;
  1537.   unsigned long *ch=(unsigned long *)display->framebuffer;
  1538.   unsigned long *pl=(unsigned long *)display->c2pbitmap[display->curbuffer].Planes[0];
  1539.   unsigned long a,b,c,d,e,f,g,h;
  1540.   unsigned long a1,b1,c1,d1,e1,f1,g1,h1;
  1541.   unsigned long t,i=planesize32;
  1542.  
  1543.   while (i--) {
  1544.     a=*ch++; b=*ch++; c=*ch++; d=*ch++;
  1545.     e=*ch++; f=*ch++; g=*ch++; h=*ch++;
  1546.  
  1547.     /*
  1548.     a7a6a5a4a3a2a1a0 b7b6b5b4b3b2b1b0 c7c6c5c4c3c2c1c0 d7d6d5d4d3d2d1d0 a
  1549.     e7e6e5e4e3e2e1e0 f7f6f5f4f3f2f1f0 g7g6g5g4g3g2g1g0 h7h6h5h4h3h2h1h0 b
  1550.     i7i6i5i4i3i2i1i0 j7j6j5j4j3j2j1j0 k7k6k5k4k3k2k1k0 l7l6l5l4l3l2l1l0 c
  1551.     m7m6m5m4m3m2m1m0 n7n6n5n4n3n2n1n0 o7o6o5o4o3o2o1o0 p7p6p5p4p3p2p1p0 d
  1552.  
  1553.     q7q6q5q4q3q2q1q0 r7r6r5r4r3r2r1r0 s7s6s5s4s3s2s1s0 t7t6t5t4t3t2t1t0 e
  1554.     u7u6u5u4u3u2u1u0 v7v6v5v4v3v2v1v0 w7w6w5w4w3w2w1w0 x7x6x5x4x3x2x1x0 f
  1555.     y7y6y5y4y3y2y1y0 z7z6z5z4z3z2z1z0 A7A6A5A4A3A2A1A0 B7B6B5B4B3B2B1B0 g
  1556.     C7C6C5C4C3C2C1C0 D7D6D5D4D3D2D1D0 E7E6E5E4E3E2E1E0 F7F6F5F4F3F2F1F0 h
  1557.  
  1558.     ->
  1559.  
  1560.     a7b7c7d7e7f7g7h7 i7j7k7l7m7n7o7p7 q7r7s7t7u7v7w7x7 y7z7A7B7C7D7E7F7
  1561.     a6b6c6d6e6f6g6h6 i6j6k6l6m6n6o6p6 q6r6s6t6u6v6w6x6 y6z6A6B6C6D6E6F6
  1562.     a5b5c5d5e5f5g5h5 i5j5k5l5m5n5o5p5 q5r5s5t5u5v5w5x5 y5z5A5B5C5D5E5F5
  1563.     a4b4c4d4e4f4g4h4 i4j4k4l4m4n4o4p4 q4r4s4t4u4v4w4x4 y4z4A4B4C4D4E4F4
  1564.  
  1565.     a3b3c3d3e3f3g3h3 i3j3k3l3m3n3o3p3 q3r3s3t3u3v3w3x3 y3z3A3B3C3D3E3F3
  1566.     a2b2c2d2e2f2g2h2 i2j2k2l2m2n2o2p2 q2r2s2t2u2v2w2x2 y2z2A2B2C2D2E2F2
  1567.     a1b1c1d1e1f1g1h1 i1j1k1l1m1n1o1p1 q1r1s1t1u1v1w1x1 y1z1A1B1C1D1E1F1
  1568.     a0b0c0d0e0f0g0h0 i0j0k0l0m0n0o0p0 q0r0s0t0u0v0w0x0 y0z0A0B0C0D0E0F0
  1569.  
  1570.     */
  1571.  
  1572.     a1=(a&~mf1)|((c&~mf1)>>8); /* a7a6a5a4a3a2a1a0 i7i6i5i4i3i2i1i0 c7c6c5c4c3c2c1c0 k7k6k5k4k3k2k1k0 */
  1573.     b1=(b&~mf1)|((d&~mf1)>>8); /* e7e6e5e4e3e2e1e0 m7m6m5m4m3m2m1m0 g7g6g5g4g3g2g1g0 o7o6o5o4o3o2o1o0 */
  1574.     c1=(e&~mf1)|((g&~mf1)>>8); /* q7q6q5q4q3q2q1q0 y7y6y5y4y3y2y1y0 s7s6s5s4s3s2s1s0 A7A6A5A4A3A2A1A0 */
  1575.     d1=(f&~mf1)|((h&~mf1)>>8); /* u7u6u5u4u3u2u1u0 C7C6C5C4C3C2C1C0 w7w6w5w4w3w2w1w0 E7E6E5E4E3E2E1E0 */
  1576.  
  1577.     e1=(a&mf1)<<8|(c&mf1); /* b7b6b5b4b3b2b1b0 j7j6j5j4j3j2j1j0 d7d6d5d4d3d2d1d0 l7l6l5l4l3l2l1l0 */
  1578.     f1=(b&mf1)<<8|(d&mf1); /* f7f6f5f4f3f2f1f0 n7n6n5n4n3n2n1n0 h7h6h5h4h3h2h1h0 p7p6p5p4p3p2p1p0 */
  1579.     g1=(e&mf1)<<8|(g&mf1); /* r7r6r5r4r3r2r1r0 z7z6z5z4z3z2z1z0 t7t6t5t4t3t2t1t0 B7B6B5B4B3B2B1B0 */
  1580.     h1=(f&mf1)<<8|(h&mf1); /* v7v6v5v4v3v2v1v0 D7D6D5D4D3D2D1D0 x7x6x5x4x3x2x1x0 F7F6F5F4F3F2F1F0 */
  1581.     
  1582.     a=(a1&mf2)<<4|(b1&mf2); /* a3a2a1a0e3e2e1e0 i3i2i1i0m3m2m1m0 c3c2c1c0g3g2g1g0 k3k2k1k0o3o2o1o0 */
  1583.     c=(c1&mf2)<<4|(d1&mf2); /* q3q2q1q0u3u2u1u0 y3y2y1y0C3C2C1C0 s3s2s1s0w3w2w1w0 A3A2A1A0E3E2E1E0 */
  1584.     e=(e1&mf2)<<4|(f1&mf2); /* b3b2b1b0f3f2f1f0 j3j2j1j0n3n2n1n0 d3d2d1d0h3h2h1h0 l3l2l1l0p3p2p1p0 */
  1585.     g=(g1&mf2)<<4|(h1&mf2); /* r3r2r1r0v3v2v1v0 z3z2z1z0D3D2D1D0 t3t2t1t0x3x2x1x0 B3B2B1B0F3F2F1F0 */
  1586.  
  1587.     b=(a1&~mf2)|((b1&~mf2)>>4); /* a7a6a5a4e7e6e5e4 i7i6i5i4m7m6m5m4 c7c6c5c4g7g6g5g4 k7k6k5k4o7o6o5o4 */
  1588.     d=(c1&~mf2)|((d1&~mf2)>>4); /* q7q6q5q4u7u6u5u4 y7y6y5y4C7C6C5C4 s7s6s5s4w7w6w5w4 A7A6A5A4E7E6E5E4 */
  1589.     f=(e1&~mf2)|((f1&~mf2)>>4); /* b7b6b5b4f7f6f5f4 j7j6j5j4n7n6n5n4 d7d6d5d4h7h6h5h4 l7l6l5l4p7p6p5p4 */
  1590.     h=(g1&~mf2)|((h1&~mf2)>>4); /* r7r6r5r4v7v6v5v4 z7z6z5z4D7D6D5D4 t7t6t5t4x7x6x5x4 B7B6B5B4F7F6F5F4 */
  1591.  
  1592.     f1=e&m3; /*     b1b0    f1f0     j1j0    n1n0     d1d0    h1h0     l1l0    p1p0 */
  1593.     f1=((f1<<2)|(f1<<16))&0xffff0000;
  1594.     t=g&m3;  /*     r1r0    v1v0     z1z0    D1D0     t1t0    x1x0     B1B0    F1F0 */
  1595.     f1|=((t<<2)|(t<<16))>>16;
  1596.  
  1597.     b1=a&m3; /*     a1a0    e1e0     i1i0    m1m0     c1c0    g1g0     k1k0    o1o0 */
  1598.     b1=((b1<<2)|(b1<<16))&0xffff0000;
  1599.     t=c&m3;  /*     q1q0    u1u0     y1y0    C1C0     s1s0    w1w0     A1A0    E1E0 */
  1600.     b1|=((t<<2)|(t<<16))>>16;
  1601.  
  1602.     pl[planesize32*0]= (f1&m5)  | ((b1&m5)<<1);
  1603.     pl[planesize32*1]= (b1&~m5) | ((f1&~m5)>>1);
  1604.  
  1605.     e1=e&~m3;
  1606.     e1=(e1|(e1<<14))&0xffff0000;
  1607.     t=g&~m3;
  1608.     e1|=(t|(t<<14))>>16;
  1609.     a1=a&~m3;
  1610.     a1=(a1|(a1<<14))&0xffff0000;
  1611.     t=c&~m3;
  1612.     a1|=(t|(t<<14))>>16;
  1613.  
  1614.     pl[planesize32*2]= (e1&m5)  | ((a1&m5)<<1);
  1615.     pl[planesize32*3]= (a1&~m5) | ((e1&~m5)>>1);
  1616.  
  1617.     h1=f&m3;
  1618.     h1=((h1<<2)|(h1<<16))&0xffff0000;
  1619.     t=h&m3;
  1620.     h1|=((t<<2)|(t<<16))>>16;
  1621.  
  1622.     d1=b&m3;
  1623.     d1=((d1<<2)|(d1<<16))&0xffff0000;
  1624.     t=d&m3;
  1625.     d1|=((t<<2)|(t<<16))>>16;
  1626.  
  1627.     pl[planesize32*4]= (h1&m5)  | ((d1&m5)<<1);
  1628.     pl[planesize32*5]= (d1&~m5) | ((h1&~m5)>>1);
  1629.  
  1630.     g1=f&~m3;
  1631.     g1=(g1|(g1<<14))&0xffff0000;
  1632.     t=h&~m3;
  1633.     g1|=(t|(t<<14))>>16;
  1634.  
  1635.     c1=b&~m3;
  1636.     c1=(c1|(c1<<14))&0xffff0000;
  1637.     t=d&~m3;
  1638.     c1|=(t|(t<<14))>>16;
  1639.  
  1640.     pl[planesize32*6]= (g1&m5)  | ((c1&m5)<<1);
  1641.     pl[planesize32*7]= (c1&~m5) | ((g1&~m5)>>1);
  1642.  
  1643.     pl++;
  1644.   }
  1645. #endif
  1646. }
  1647.  
  1648.  
  1649. /* written by Harry "Piru" Sintonen, and you can see it:)
  1650. */
  1651.  
  1652. void awinitc2pham6(struct awdisplay *display) {
  1653.  
  1654.   /* c2p specific init */
  1655.  
  1656.   ULONG *p4,*p5,cnt,b,max;
  1657.  
  1658.   if ( (!display->windowmode) && (display->isham6) ) {
  1659.  
  1660.     max=display->dbuffer?2:1;
  1661.  
  1662.     for (b=0; b<max; b++) {
  1663.       p4=(ULONG *)display->c2pbitmap[b].Planes[4];
  1664.       p5=(ULONG *)display->c2pbitmap[b].Planes[5];
  1665.       cnt=display->scrwidth*display->height/32;  /* w*h/8/4 */
  1666.       while (cnt--) *p4++=0x33333333, *p5++=0x44444444;
  1667.     }
  1668.   }
  1669.  
  1670.  
  1671. #if AW_USEC2PHAM668K
  1672.  
  1673.   awinitchunky2planarham6(
  1674.     display->framebuffer,
  1675.     display->scrwidth,
  1676.     display->height,
  1677.     display->dstdepth);
  1678.  
  1679. #else
  1680. #endif
  1681. }
  1682.  
  1683. void awdoc2pham6(struct awdisplay *display) {
  1684.  
  1685.   /* c2p specific stuff */
  1686.  
  1687. #if AW_USEC2PHAM668K
  1688.  
  1689.   awchunky2planarham6(display->c2pbitmap[display->curbuffer].Planes[0]);
  1690.  
  1691. #else
  1692.  
  1693.   unsigned long planesize32=display->scrwidth*display->height/32; /* w*h/8/4 */
  1694.   unsigned long *ch=(unsigned long *)display->framebuffer;
  1695.   unsigned long *pl=(unsigned long *)display->c2pbitmap[display->curbuffer].Planes[0];
  1696.   unsigned long a,b,c,d,a1,b1,c1,d1;
  1697.   unsigned long i=planesize32;
  1698.  
  1699.   while (i--) {
  1700.     a=*ch++; b=*ch++; c=*ch++; d=*ch++;
  1701.  
  1702.     /* rrrrrggg gggbbbbb RRRRRGGG GGGBBBBB -> ggggrrrr bbbbbbbb GGGGRRRR BBBBBBBB */
  1703.     a=(a&0x07800780)<<5 | (a&0xf000f000)>>4 | (a&0x001e001e)<<3 | (a&0x001e001e)>>1;
  1704.     b=(b&0x07800780)<<5 | (b&0xf000f000)>>4 | (b&0x001e001e)<<3 | (b&0x001e001e)>>1;
  1705.     c=(c&0x07800780)<<5 | (c&0xf000f000)>>4 | (c&0x001e001e)<<3 | (c&0x001e001e)>>1;
  1706.     d=(d&0x07800780)<<5 | (d&0xf000f000)>>4 | (d&0x001e001e)<<3 | (d&0x001e001e)>>1;
  1707.  
  1708.     /*
  1709.     You guys with more experience with c2ps probably know better ways to do
  1710.     this. Feel free to improve it. :)
  1711.  
  1712.     a3a2a1a0 b3b2b1b0 c3c2c1c0 d3d2d1d0 e3e2e1e0 f3f2f1f0 g3g2g1g0 h3h2h1h0 a
  1713.     i3i2i1i0 j3j2j1j0 k3k2k1k0 l3l2l1l0 m3m2m1m0 n3n2n1n0 o3o2o1o0 p3p2p1p0 b
  1714.     q3q2q1q0 r3r2r1r0 s3s2s1s0 t3t2t1t0 u3u2u1u0 v3v2v1v0 w3w2w1w0 x3x2x1x0 c
  1715.     y3y2y1y0 z3z2z1z0 A3A2A1A0 B3B2B1B0 C3C2C1C0 D3D2D1D0 E3E2E1E0 F3F2F1F0 d
  1716.  
  1717.     1        9        17       25       2        10       18       26
  1718.     3        11       19       27       4        12       20       28
  1719.     5        13       21       29       6        14       22       30
  1720.     7        15       23       31       8        16       24       32
  1721.  
  1722.  
  1723.                       -----------                         -----------
  1724.     1        9        17       25       2        10       18       26
  1725.     -----------                         -----------
  1726.     3        11       19       27       4        12       20       28
  1727.                       ===========                         ===========
  1728.     5        13       21       29       6        14       22       30
  1729.     ===========                         ===========
  1730.     7        15       23       31       8        16       24       32
  1731.  
  1732.     ->
  1733.  
  1734.     1        9        3        11       2        10       4        12
  1735.     17       25       19       27       18       26       20       28
  1736.     5        13       7        15       6        14       8        16
  1737.     21       29       23       31       22       30       24       32
  1738.  
  1739.  
  1740.              --1               --2      --1               --2
  1741.     1        9        3        11       2        10       4        12
  1742.  
  1743.     17       25       19       27       18       26       20       28
  1744.  
  1745.     5        13       7        15       6        14       8        16
  1746.  
  1747.     21       29       23       31       22       30       24       32
  1748.  
  1749.     ->
  1750.  
  1751.     1        2        3        4        9        10       11       12
  1752.     17       18       19       20       25       26       27       28
  1753.     5        6        7        8        13       14       15       16
  1754.     21       22       23       24       29       30       31       32
  1755.  
  1756.  
  1757.                                         -----------------------------
  1758.     1        2        3        4        9        10       11       12
  1759.                                         .............................
  1760.     17       18       19       20       25       26       27       28
  1761.     -----------------------------
  1762.     5        6        7        8        13       14       15       16
  1763.     .............................
  1764.     21       22       23       24       29       30       31       32
  1765.  
  1766.     ->
  1767.  
  1768.     1        2        3        4        5        6        7        8 
  1769.     17       18       19       20       21       22       23       24
  1770.     9        10       11       12       13       14       15       16
  1771.     25       26       27       28       29       30       31       32
  1772.  
  1773.     (a&0x11111111)<<3|(c&0x11111111)<<2|(b&0x11111111)<<1|(d&0x11111111);
  1774.     (a&0x22222222)<<2|(c&0x22222222)<<1|(b&0x22222222)   |(d&0x22222222)>>1;
  1775.     (a&0x44444444)<<1|(c&0x44444444)   |(b&0x44444444)>>1|(d&0x44444444)>>2;
  1776.     (a&0x88888888)   |(c&0x88888888)>>1|(b&0x88888888)>>2|(d&0x88888888)>>3;
  1777.  
  1778.     ->
  1779.  
  1780.     a3b3c3d3 e3f3g3h3 i3j3k3l3 m3n3o3p3  q3r3s3t3 u3v3w3x3 y3z3A3B3 C3D3E3F3
  1781.     a2b2c2d2 e2f2g2h2 i2j2k2l2 m2n2o2p2  q2r2s2t2 u2v2w2x2 y2z2A2B2 C2D2E2F2
  1782.     a1b1c1d1 e1f1g1h1 i1j1k1l1 m1n1o1p1  q1r1s1t1 u1v1w1x1 y1z1A1B1 C1D1E1F1
  1783.     a0b0c0d0 e0f0g0h0 i0j0k0l0 m0n0o0p0  q0r0s0t0 u0v0w0x0 y0z0A0B0 C0D0E0F0
  1784.  
  1785.     */
  1786.  
  1787.     a1 = (a & 0xff00ff00) | ((b & 0xff00ff00)>>8);
  1788.     c1 = (c & 0xff00ff00) | ((d & 0xff00ff00)>>8);
  1789.     b1 = (b & 0x00ff00ff) | ((a & 0x00ff00ff)<<8);
  1790.     d1 = (d & 0x00ff00ff) | ((c & 0x00ff00ff)<<8);
  1791.  
  1792.     a = (a1 & 0xf0f00f0f) | ((a1 & 0x0f0f0000)>>12) | ((a1 & 0xf0f0)<<12);
  1793.     b = (b1 & 0xf0f00f0f) | ((b1 & 0x0f0f0000)>>12) | ((b1 & 0xf0f0)<<12);
  1794.     c = (c1 & 0xf0f00f0f) | ((c1 & 0x0f0f0000)>>12) | ((c1 & 0xf0f0)<<12);
  1795.     d = (d1 & 0xf0f00f0f) | ((d1 & 0x0f0f0000)>>12) | ((d1 & 0xf0f0)<<12);
  1796.  
  1797.     a1 = (a & 0xffff0000) | (c >> 16);
  1798.     b1 = (b & 0xffff0000) | (d >> 16);
  1799.     c1 = (a << 16) | (c & 0xffff);
  1800.     d1 = (b << 16) | (d & 0xffff);
  1801.  
  1802.     pl[planesize32*0]=
  1803.       (a1&0x11111111)<<3 | (c1&0x11111111)<<2 |
  1804.       (b1&0x11111111)<<1 | (d1&0x11111111);
  1805.     pl[planesize32*1]=
  1806.       (a1&0x22222222)<<2 | (c1&0x22222222)<<1 |
  1807.       (b1&0x22222222)    | (d1&0x22222222)>>1;
  1808.     pl[planesize32*2]=
  1809.       (a1&0x44444444)<<1 | (c1&0x44444444) |
  1810.       (b1&0x44444444)>>1 | (d1&0x44444444)>>2;
  1811.     pl[planesize32*3]=
  1812.       (a1&0x88888888)    | (c1&0x88888888)>>1 |
  1813.       (b1&0x88888888)>>2 | (d1&0x88888888)>>3;
  1814.  
  1815.     pl++;
  1816.   }
  1817. #endif
  1818. }
  1819.  
  1820. void awfreechunky(struct awchunky *chunky) {
  1821.   if (chunky) {
  1822.     if (chunky->memory) free(chunky->memory);
  1823.     free(chunky);
  1824.   }
  1825. }
  1826.  
  1827. struct awchunky *awinitchunkystruct(struct awdisplay *display,
  1828.   ULONG width,ULONG height,ULONG depth) {
  1829.   struct awchunky *chunky;
  1830.  
  1831.   chunky=malloc(sizeof(struct awchunky));
  1832.   if (chunky) {
  1833.     memset(chunky,0,sizeof(struct awchunky));
  1834.  
  1835.     chunky->width_align=awalign(width,32);
  1836.     chunky->width=width;
  1837.     chunky->height=height;
  1838.     chunky->depth=depth;
  1839.   }
  1840.   return chunky;
  1841. }
  1842.  
  1843. struct awchunky *awallocchunky(struct awdisplay *display,ULONG width,
  1844.   ULONG height,ULONG depth) {
  1845.  
  1846.   ULONG size;
  1847.   struct awchunky *chunky;
  1848.  
  1849.   if ( (!width) || (!height) || (!depth) ) return NULL;
  1850.   if ( (depth!=8) && (depth!=16) ) return NULL;
  1851.  
  1852.   chunky=awinitchunkystruct(display,width,height,depth);
  1853.   if (chunky) {
  1854.  
  1855.     size=(depth>>3)*
  1856.       chunky->width_align*chunky->height+63+AW_SANITY;
  1857.  
  1858.     chunky->memory=malloc(size);
  1859.      if (chunky->memory) {
  1860.       memset(chunky->memory,0,size);
  1861.       chunky->framebuffer=(UBYTE *)awalign(chunky->memory,32);
  1862.     } else {
  1863.       awfreechunky(chunky); chunky=NULL;
  1864.     }
  1865.   }
  1866.   return chunky;
  1867. }
  1868.  
  1869. void awfreepens(struct awdisplay *display) {
  1870.  
  1871. #if defined(AW_PPC)
  1872.   struct Caos kaaos;
  1873.  
  1874.   /* -*- odump by Harry "Piru" Sintonen */
  1875.   static const ULONG awfreepensinner[]={
  1876.     0x48e73f3e,0x26482849,0x2e3c0000,0x01004a14,
  1877.     0x670a7000,0x204a1013,0x4eaefc4c,0x421c421b,
  1878.     0x538766ea,0x4cdf7cfc,0x4e754e71};
  1879.   /* -*- */
  1880.  
  1881.   if (display) {
  1882.  
  1883.     kaaos.a0=(ULONG)display->remap;
  1884.     kaaos.a1=(ULONG)display->penal;
  1885.     kaaos.a2=(ULONG)display->screen->ViewPort.ColorMap;
  1886.     kaaos.a6=(ULONG)display->GfxBase;
  1887.     kaaos.caos_Un.Function=(APTR)awfreepensinner;
  1888.     kaaos.M68kCacheMode=IF_CACHEFLUSHALL;
  1889.     kaaos.PPCCacheMode=IF_CACHEFLUSHALL;
  1890.     PPCCallM68k(&kaaos);
  1891.   }
  1892.  
  1893. #else
  1894.  
  1895.   struct GfxBase *GfxBase;
  1896.   LONG x;
  1897.  
  1898.   if (display) {
  1899.  
  1900.     GfxBase=display->GfxBase;
  1901.     for (x=0; x<256; x++) {
  1902.       if (display->penal[x]) {
  1903.         ReleasePen(display->screen->ViewPort.ColorMap,
  1904.           (ULONG)display->remap[x]);
  1905.         display->penal[x]=0;
  1906.       }
  1907.       display->remap[x]=0;
  1908.     }
  1909.   }
  1910. #endif
  1911. }
  1912.  
  1913. void awicleardisplay(struct awdisplay *display) {
  1914.   struct GfxBase *GfxBase;
  1915.  
  1916.   if ( (display) && (display->window) ) {
  1917.     GfxBase=display->GfxBase;
  1918.     EraseRect(display->window->RPort,display->window->BorderLeft,
  1919.       display->window->BorderTop,display->window->BorderLeft+
  1920.       awtoinnerw(display,display->window->Width)-1,display->window->
  1921.       BorderTop+awtoinnerh(display,display->window->Height)-1);
  1922.   }
  1923. }
  1924.  
  1925. void awclosedisplay(struct awdisplay *display) {
  1926.   struct ExecBase *SysBase;
  1927.   struct GfxBase *GfxBase;
  1928.   struct IntuitionBase *IntuitionBase;
  1929.   struct Library *DOSBase;
  1930. #if AW_CGXVIDEOSUPPORT
  1931.   struct Library *CGXVideoBase;
  1932. #endif
  1933.  
  1934.   if (display) {
  1935.     SysBase=display->SysBase;
  1936.     GfxBase=display->GfxBase;
  1937.     IntuitionBase=display->IntuitionBase;
  1938.     DOSBase=display->DOSBase;
  1939.  
  1940.     awicleardisplay(display);
  1941.     if (display->native) WaitBlit();
  1942.  
  1943.     if (display->windowmode) {
  1944.  
  1945. #if AW_CGXVIDEOSUPPORT
  1946.       if (display->vlhandle) {
  1947.         CGXVideoBase=display->CGXVideoBase;
  1948.         DetachVLayer(display->vlhandle);
  1949.         DeleteVLayerHandle(display->vlhandle);
  1950.         display->vlhandle=NULL;
  1951.         display->vlwidth=0; display->vlheight=0;
  1952.       }
  1953. #endif
  1954.  
  1955.       awfreepens(display);
  1956.  
  1957.       if (display->c2pplanes[0]) {
  1958.         FreeVec(display->c2pplanes[0]); display->c2pplanes[0]=NULL;
  1959.       }
  1960.       if (display->memory) {
  1961.         free(display->memory); display->memory=NULL;
  1962.       }
  1963.       if (display->tempbm) {
  1964.         FreeBitMap(display->tempbm); display->tempbm=NULL;
  1965.       }
  1966.  
  1967.       if (display->window) {
  1968.         display->left=display->window->LeftEdge;
  1969.         display->top=display->window->TopEdge;
  1970.         display->prevwidth=awtoinnerw(display,display->window->Width);
  1971.         display->prevheight=awtoinnerh(display,display->window->Height);
  1972.         CloseWindow(display->window); display->window=NULL;
  1973.       }
  1974.  
  1975.       if (display->screen) {
  1976.         display->prevscreen=awscreensum(display->screen);
  1977.         UnlockPubScreen(NULL,display->screen); display->screen=NULL;
  1978.       }
  1979.  
  1980.     } else {
  1981.  
  1982.       if (display->memory) {
  1983.         free(display->memory); display->memory=NULL;
  1984.       }
  1985.       if (display->tempbm) {
  1986.         FreeBitMap(display->tempbm); display->tempbm=NULL;
  1987.       }
  1988.  
  1989.       if (display->window) {
  1990.         CloseWindow(display->window); display->window=NULL;
  1991.       }
  1992.  
  1993.       if (display->pointerobject) {
  1994.         DisposeObject(display->pointerobject);
  1995.         display->pointerobject=NULL;
  1996.       }
  1997.  
  1998.       if ( (display->sbuf[0]) &&
  1999.            (display->sbuf[1]) &&
  2000.            (display->sbports[AW_WRITEPORT]) &&
  2001.            (display->sbports[AW_DISPPORT]) ) {
  2002.  
  2003.         if ( (!display->safetochange) ||
  2004.              (!display->safetowrite) ) {
  2005.  
  2006.           /* wait some time for (possible) pending messages to arrive.
  2007.              This hacky thing is here to "fix" some CGFX stuff.
  2008.           */
  2009.           WaitTOF(); WaitTOF();
  2010.  
  2011.           /* cleanup pending messages */
  2012.           while (GetMsg(display->sbports[AW_WRITEPORT]));
  2013.  
  2014.           if (display->waitswap) {
  2015.             /* cleanup pending messages */
  2016.             while (GetMsg(display->sbports[AW_DISPPORT]));
  2017.           }
  2018.         }
  2019.       }
  2020.  
  2021.       if (display->screen) {
  2022.         if (display->native) WaitBlit();
  2023.  
  2024.         if (display->sbuf[1]) {
  2025.           FreeScreenBuffer(display->screen,display->sbuf[1]);
  2026.           display->sbuf[1]=NULL;
  2027.         }
  2028.  
  2029.         if (display->sbuf[0]) {
  2030.           FreeScreenBuffer(display->screen,display->sbuf[0]);
  2031.           display->sbuf[0]=NULL;
  2032.         }
  2033.       }
  2034.  
  2035.       if (display->sbports[AW_WRITEPORT]) {
  2036.         DeleteMsgPort(display->sbports[AW_WRITEPORT]);
  2037.         display->sbports[AW_WRITEPORT]=NULL;
  2038.       }
  2039.  
  2040.       if (display->sbports[AW_DISPPORT]) {
  2041.         if (display->waitswap) {
  2042.           DeleteMsgPort(display->sbports[AW_DISPPORT]);
  2043.         }
  2044.         display->sbports[AW_DISPPORT]=NULL;
  2045.       }
  2046.  
  2047.       if (display->screen) {
  2048.         while (!CloseScreen(display->screen)) {
  2049.           DisplayBeep(display->screen);
  2050.           Delay(25);
  2051.         }
  2052.         display->screen=NULL;
  2053.       }
  2054.  
  2055.       if (display->c2pplanes[1]) {
  2056.         FreeVec(display->c2pplanes[1]); display->c2pplanes[1]=NULL;
  2057.       }
  2058.  
  2059.       if (display->c2pplanes[0]) {
  2060.         FreeVec(display->c2pplanes[0]); display->c2pplanes[0]=NULL;
  2061.       }
  2062.  
  2063.     }
  2064.  
  2065.     if (display->fblitptrbm) {
  2066.       FreeBitMap(display->fblitptrbm); display->fblitptrbm=NULL;
  2067.     }
  2068.   }
  2069. }
  2070.  
  2071. void awdeletedisplay(struct awdisplay *display) {
  2072.   struct ExecBase *SysBase;
  2073.  
  2074.   if (display) {
  2075.     SysBase=display->SysBase;
  2076.  
  2077.     awclosedisplay(display);
  2078.  
  2079.     if (display->DOSBase) CloseLibrary(display->DOSBase);
  2080.     if (display->remap332) free(display->remap332);
  2081.     if (display->UtilityBase) CloseLibrary(display->UtilityBase);
  2082. #if AW_CGXVIDEOSUPPORT
  2083.     if (display->CGXVideoBase) CloseLibrary(display->CGXVideoBase);
  2084. #endif
  2085.     if (display->CyberGfxBase) CloseLibrary(display->CyberGfxBase);
  2086.     /* display->TimerBase do nothing */
  2087.     if (display->IntuitionBase) CloseLibrary((struct Library *)
  2088.       display->IntuitionBase);
  2089.     if (display->GfxBase) CloseLibrary((struct Library *)
  2090.       display->GfxBase);
  2091.  
  2092.     free(display);
  2093.   }
  2094. }
  2095.  
  2096. /*
  2097. inline UBYTE awrgb16to332(UWORD x) {
  2098.   return ((x>>8)&(7<<5)) | ((x>>6)&(7<<2)) | ((x>>3)&3);
  2099. }
  2100. */
  2101.  
  2102. void awremap(struct awdisplay *display) {
  2103.   struct GfxBase *GfxBase;
  2104.   ULONG table[256*3+2],x,max,r,g,b,f,*pal;
  2105.  
  2106. #if defined(AW_PPC)
  2107.   struct Caos kaaos;
  2108.  
  2109.   /* -*- odump by Harry "Piru" Sintonen */
  2110.   static const ULONG awremapinner[]={
  2111.     0x48e73f3e,0x2e002848,0x2a4942a7,0x42a74879,
  2112.     0x84000001,0x2f014879,0x84000000,0x4eaeff1c,
  2113.     0x7c004a12,0x670a7000,0x204b1015,0x4eaefc4c,
  2114.     0x421a528d,0x530666ea,0x45eaff00,0x4bedff00,
  2115.     0x78ff204b,0x4cdc000e,0x224f4eae,0xfcb82200,
  2116.     0x5281660a,0x222cfff8,0x4eaefc10,0x600414fc,
  2117.     0x00011ac0,0x538766da,0x4fef0014,0x4cdf7cfc,
  2118.     0x4e754e71,0x00000000,0x00000000,0x00000000,
  2119.     0};
  2120.   /* -*- */
  2121. #else
  2122.   LONG p;
  2123. #endif
  2124.  
  2125.   pal=(display->srcdepth==16)?display->pal332:display->palette;
  2126.   max=(display->srcdepth==16)?256:display->palentries;
  2127.  
  2128.   if ( (display->window) && (max) ) {
  2129.  
  2130.     GfxBase=display->GfxBase;
  2131.  
  2132.     if ( (!display->windowmode) && (display->isham6) ) {
  2133.       max=16;
  2134.       table[0]=max<<16;
  2135.       for (x=0; x<max; x++) {
  2136.         g=x<<4|x;
  2137.         table[x*3+1]=0;
  2138.         f=(g&0xf)<<4|(g&0xf);
  2139.         table[x*3+2]=(g<<24)|(f<<16)|(f<<8)|f;
  2140.         table[x*3+3]=0;
  2141.       }
  2142.       table[max*3+1]=0;
  2143.  
  2144.     } else {
  2145.  
  2146.       table[0]=max<<16;
  2147.       for (x=0; x<max; x++) {
  2148.  
  2149.         r=(pal[x]>>16)&0xff;
  2150.         g=(pal[x]>>8)&0xff;
  2151.         b=pal[x]&0xff;
  2152.  
  2153.         f=(r&0xf)<<4|(r&0xf);
  2154.         table[x*3+1]=(r<<24)|(f<<16)|(f<<8)|f;
  2155.  
  2156.         f=(g&0xf)<<4|(g&0xf);
  2157.         table[x*3+2]=(g<<24)|(f<<16)|(f<<8)|f;
  2158.  
  2159.         f=(b&0xf)<<4|(b&0xf);
  2160.         table[x*3+3]=(b<<24)|(f<<16)|(f<<8)|f;
  2161.       }
  2162.       table[max*3+1]=0;
  2163.     }
  2164.  
  2165.     if (display->windowmode) {
  2166.  
  2167.       if ( !(display->truecolor && display->wlutpa) ) {
  2168.  
  2169.         awicleardisplay(display);
  2170.  
  2171.         /* (re)build remap table */
  2172.  
  2173. #if defined(AW_PPC)
  2174.         kaaos.a0=(ULONG)&table[1];
  2175.         kaaos.a1=(ULONG)display->remap;
  2176.         kaaos.a2=(ULONG)display->penal;
  2177.         kaaos.a3=(ULONG)display->screen->ViewPort.ColorMap;
  2178.         kaaos.a6=(ULONG)display->GfxBase;
  2179.         kaaos.d0=(ULONG)max;
  2180.         kaaos.d1=(ULONG)AW_PRECISION;
  2181.         kaaos.caos_Un.Function=(APTR)awremapinner;
  2182.         kaaos.M68kCacheMode=IF_CACHEFLUSHALL;
  2183.         kaaos.PPCCacheMode=IF_CACHEFLUSHALL;
  2184.         PPCCallM68k(&kaaos);
  2185. #else
  2186.         if (display->native) WaitBlit();
  2187.  
  2188.         for (x=0; x<256; x++) {
  2189.           if (display->penal[x]) {
  2190.             ReleasePen(display->screen->ViewPort.ColorMap,
  2191.               (ULONG)display->remap[x]);
  2192.             display->penal[x]=0;
  2193.           }
  2194.           display->remap[x]=0;
  2195.         }
  2196.  
  2197.         for (x=0; x<max; x++) {
  2198.  
  2199.           p=ObtainBestPen(
  2200.             display->screen->ViewPort.ColorMap,
  2201.             table[x*3+1],
  2202.             table[x*3+2],
  2203.             table[x*3+3],
  2204.             OBP_Precision,AW_PRECISION,
  2205.             OBP_FailIfBad,0,
  2206.             TAG_DONE);
  2207.  
  2208.           if (p!=-1) {
  2209.             display->penal[x]=1;
  2210.           } else {
  2211.             p=FindColor(
  2212.               display->screen->ViewPort.ColorMap,
  2213.               table[x*3+1],
  2214.               table[x*3+2],
  2215.               table[x*3+3],
  2216.               -1L);
  2217.           }
  2218.  
  2219.           display->remap[x]=(UBYTE)p;
  2220.         }
  2221. #endif
  2222.  
  2223.         for (x=0; x<65536; x+=4) {
  2224.           display->remap332[x+0]=display->remap[awrgb16to332(x+0)];
  2225.           display->remap332[x+1]=display->remap[awrgb16to332(x+1)];
  2226.           display->remap332[x+2]=display->remap[awrgb16to332(x+2)];
  2227.           display->remap332[x+3]=display->remap[awrgb16to332(x+3)];
  2228.         }
  2229.  
  2230.       }
  2231.     
  2232.     } else {
  2233.  
  2234.       LoadRGB32(&display->screen->ViewPort,table);
  2235.  
  2236.     }
  2237.   }
  2238. }
  2239.  
  2240. ULONG awsetpalette(struct awdisplay *display,ULONG *palette,ULONG n) {
  2241.  
  2242.   if ( (n<1) || (n>256) ) return 0;
  2243.   display->palentries=n;
  2244.   memcpy(display->palette,palette,sizeof(ULONG)*n);
  2245.  
  2246.   if (!display->stoprender) {
  2247.     /* really do it */
  2248.     awremap(display);
  2249.   }
  2250.  
  2251.   return 1;
  2252. }
  2253.  
  2254. void *awiallocbitmap(struct awdisplay *display,struct BitMap *bm,
  2255.   ULONG width,ULONG height,ULONG depth,ULONG memtype) {
  2256.  
  2257.   ULONG size,p,w;
  2258.   UBYTE *mem;
  2259.   struct ExecBase *SysBase=display->SysBase;
  2260.   struct GfxBase *GfxBase=display->GfxBase;
  2261.  
  2262.   if ( (depth>=1) && (depth<=8) ) {
  2263.  
  2264.     w=awalign(width,32);
  2265.  
  2266.     size=(w>>4)*2*height;
  2267.  
  2268.     mem=AllocVec(size*depth+63+AW_SANITY,memtype);
  2269.     if (mem) {
  2270.       InitBitMap(bm,depth,w,height);
  2271.       for (p=0; p<depth; p++) {
  2272.         bm->Planes[p]=(void *)(awalign(mem,32)+p*size);
  2273.       }
  2274.       return mem;
  2275.     }
  2276.   }
  2277.   return NULL;
  2278. }
  2279.  
  2280. ULONG awreopen(struct awdisplay *display) {
  2281.   ULONG mul,size,ret=1;
  2282.   struct ExecBase *SysBase;
  2283.   struct GfxBase *GfxBase;
  2284.  
  2285.   if (display) {
  2286.     SysBase=display->SysBase;
  2287.     GfxBase=display->GfxBase;
  2288.     if (display->native) WaitBlit();
  2289.  
  2290.     if (display->windowmode) {
  2291.  
  2292.       if (display->c2pplanes[0]) FreeVec(display->c2pplanes[0]);
  2293.       if (display->memory) free(display->memory);
  2294.  
  2295.       display->width=awtoinnerw(display,display->window->Width);
  2296.       display->height=awtoinnerh(display,display->window->Height);
  2297.       display->width_align=awalign(display->width,display->widthaligner);
  2298.       display->pixperrow=display->width_align;
  2299.       display->scrwidth=display->width_align;
  2300.     }
  2301.     if (display->tempbm) FreeBitMap(display->tempbm);
  2302.  
  2303.     display->tempbm=awallocbm(
  2304.       display->width_align,1,display->dstdepth,
  2305.       0L,display->window->RPort->BitMap,0);
  2306.  
  2307.     if (display->tempbm) {
  2308.       memcpy(&display->temprp,display->windowmode?
  2309.         display->window->RPort:&display->screen->RastPort,
  2310.         sizeof(struct RastPort));
  2311.       display->temprp.Layer=NULL;
  2312.       display->temprp.BitMap=display->tempbm;
  2313.  
  2314.       /* set up buffering renderrp */
  2315.       if (!display->windowmode) {
  2316.         memcpy(&display->renderrp,&display->screen->RastPort,
  2317.           sizeof(struct RastPort));
  2318.       }
  2319.  
  2320.       if (display->useargb16 && display->cgfx &&
  2321.           display->truecolor) {
  2322.         /* ARGB = 4 bytes per pixel */
  2323.         mul=4;
  2324.       } else {
  2325.         /* chunky depth >>3 bytes per pixel
  2326.             8 = 1
  2327.            16 = 2 */
  2328.         mul=display->srcdepth>>3;
  2329.       }
  2330.  
  2331.       size=mul*
  2332.         display->width_align*display->height+AW_SANITY+63;
  2333.  
  2334.       display->memory=malloc(size);
  2335.       if (display->memory) {
  2336.         memset(display->memory,0,size);
  2337.         display->framebuffer=(UBYTE *)awalign(display->memory,32);
  2338.  
  2339.         if (display->native) {
  2340.  
  2341.           if (display->windowmode) {
  2342.  
  2343.             display->c2pplanes[0]=awiallocbitmap(
  2344.               display,&display->c2pbitmap[0],
  2345.               display->width_align,display->height,8,
  2346.               display->fblit?MEMF_PUBLIC:MEMF_CHIP);
  2347.  
  2348.             if (display->c2pplanes[0]) {
  2349.  
  2350.               display->curbuffer=0;  /* for window c2p */
  2351.               awinitc2p(display);
  2352.  
  2353.             } else {
  2354.               AW_VPRINT("awin: could not allocate c2pbitmap[0] chip memory\n");
  2355.               awclosedisplay(display); return 0L;
  2356.             }
  2357.  
  2358.           } else {
  2359.  
  2360.             if (display->isham6) {
  2361.               awinitc2pham6(display);
  2362.             } else {
  2363.               awinitc2p(display);
  2364.             }
  2365.  
  2366.           }
  2367.  
  2368.         }
  2369.  
  2370.         /*printf("reopen succeeded\n");
  2371.         */
  2372.  
  2373. #if AW_DEBUG
  2374.         printf("width: %ld (%ld/%ld) height: %ld c2pbitmap planes: 0x%08lx\n"
  2375.                "native: %ld fblit: %ld slowwpa: %ld cgfx: %ld srcdepth: %ld dstdepth: %ld\n"
  2376.                "truecolor: %ld wlutpa: %ld waitswap: %ld directdraw: %ld\n",
  2377.         display->width,display->width_align,display->widthaligner,display->height,
  2378.         (ULONG)display->c2pbitmap[0].Planes[0],display->native,
  2379.         display->fblit,display->slowwpa8,display->cgfx,
  2380.         display->srcdepth,display->dstdepth,display->truecolor,
  2381.         display->wlutpa,display->waitswap,display->directdraw);
  2382. #endif
  2383.  
  2384.       } else {
  2385.         AW_VPRINT1("awin: could not allocate %ld bytes for framebuffer\n",size);
  2386.         awclosedisplay(display); ret=0;
  2387.       }
  2388.     } else {
  2389.       AW_VPRINT("awin: could not alloc temp bitmap\n");
  2390.       awclosedisplay(display); ret=0;
  2391.     }
  2392.   }
  2393.   return ret;
  2394. }
  2395.  
  2396. ULONG awibest16cmodeid(struct awdisplay *display,
  2397.   ULONG width,ULONG height) {
  2398.  
  2399.   struct Library *CyberGfxBase;
  2400.   struct CyberModeNode *cmodelist,*cmoden;
  2401.   ULONG serror=0x7fffffff,error,targetarea,
  2402.     camodeid=INVALID_ID,sw=0x7fffffff,sh=0x7fffffff,
  2403.     smodeid=INVALID_ID;
  2404.  
  2405.   struct TagItem acml_tags[3];
  2406.  
  2407.   if ( (display) && (display->CyberGfxBase) ) {
  2408.     CyberGfxBase=display->CyberGfxBase;
  2409.  
  2410.     targetarea=width*height;
  2411.  
  2412.     acml_tags[0].ti_Tag=CYBRMREQ_MinDepth; acml_tags[0].ti_Data=16;
  2413.     acml_tags[1].ti_Tag=CYBRMREQ_MaxDepth; acml_tags[1].ti_Data=16;
  2414.     acml_tags[2].ti_Tag=TAG_DONE;
  2415.     cmodelist=(struct CyberModeNode *)AllocCModeListTagList(acml_tags);
  2416.  
  2417.     if (cmodelist) {
  2418.       cmoden=cmodelist;
  2419.       while ( (cmoden=(struct CyberModeNode *)cmoden->Node.ln_Succ)
  2420.         ->Node.ln_Succ ) {
  2421.         if ( (GetCyberIDAttr(CYBRIDATTR_PIXFMT,cmoden->DisplayID)
  2422.               ==PIXFMT_RGB16) && (cmoden->Depth==16) ) {
  2423.  
  2424.           if ( (cmoden->Width<width) &&
  2425.                (cmoden->Height<height) ) {
  2426.             if ( (cmoden->Width<=sw) &&
  2427.                  (cmoden->Height<=sh) ) {
  2428.  
  2429.               smodeid=cmoden->DisplayID;
  2430.               sw=cmoden->Width;
  2431.               sh=cmoden->Height;
  2432.             }
  2433.           }
  2434.           error=cmoden->Width*cmoden->Height;
  2435.           error=(error>targetarea)?(error-targetarea):(targetarea-error);
  2436.           if (error<serror) {
  2437.             camodeid=cmoden->DisplayID;
  2438.             serror=error;
  2439.           }
  2440.         }
  2441.       }
  2442.       FreeCModeList((struct List *)cmodelist);
  2443.  
  2444.       if (smodeid!=INVALID_ID) return smodeid;
  2445.       if (camodeid!=INVALID_ID) return camodeid;
  2446.     }
  2447.   }
  2448.   return INVALID_ID;
  2449. }
  2450.  
  2451.  
  2452. struct awdisplay *awcreatedisplay(void) {
  2453.   struct awdisplay *display;
  2454.   struct MsgPort *port;
  2455.   struct timerequest *treq;
  2456.   struct ExecBase *SysBase=(*((struct ExecBase **)4));
  2457.   struct Library *CyberGfxBase;
  2458.   struct Library *cgxsystemBase;
  2459.   ULONG wpa8func,rombase,x;
  2460.   struct SignalSemaphore *setpatchsema;
  2461.   struct TagItem bcmid_tags[3];
  2462.  
  2463.   if (SysBase->LibNode.lib_Version<39) {
  2464.     printf("awin: requires at least AmigaOS 3.0\n");
  2465.     return NULL;
  2466.   }
  2467.  
  2468.   Forbid();
  2469.   setpatchsema=FindSemaphore("« SetPatch »");
  2470.   Permit();
  2471.  
  2472.   if (!setpatchsema) {
  2473.     printf("awin: SetPatch not run\n");
  2474.     return NULL;
  2475.   }
  2476.  
  2477.   display=malloc(sizeof(struct awdisplay));
  2478.   if (display) {
  2479.     memset(display,0,sizeof(struct awdisplay));
  2480.     display->SysBase=SysBase;
  2481.  
  2482.     display->GfxBase=(struct GfxBase *)
  2483.       OpenLibrary(GRAPHICSNAME,39L);
  2484.     if (display->GfxBase) {
  2485.   
  2486.       display->IntuitionBase=(struct IntuitionBase *)
  2487.         OpenLibrary("intuition.library",39L);
  2488.       if (display->IntuitionBase) {
  2489.     
  2490.         display->v40 = display->GfxBase->LibNode.lib_Version>=40 ? 1 : 0;
  2491.         /* debug
  2492.         display->v40=0;
  2493.         */
  2494.  
  2495.         /* if not akiko hardware... */
  2496.         if ( !((display->v40) && (display->GfxBase->ChunkyToPlanarPtr)) ) {
  2497.  
  2498.           rombase=((ULONG)SysBase->LibNode.lib_Node.ln_Name)&0xffff0000;
  2499.           wpa8func=*((ULONG *)((ULONG)display->GfxBase-0x312+2));
  2500.  
  2501.           if ( ((wpa8func>rombase) &&
  2502.                (wpa8func<(rombase+0x80000))) ||
  2503.                (wpa8func<=SysBase->MaxLocMem) ) {
  2504.             /* WPA8 is in ROM or chip memory */
  2505.             display->slowwpa8=1;
  2506.           } else {
  2507.             /* WPA8 is in fastram, check for SetPatch WPA8 */
  2508.             if ( (*((ULONG *)(wpa8func+0))==0x48E73F38) &&
  2509.                  (*((ULONG *)(wpa8func+4))==0x944048C2) &&
  2510.                  (*((ULONG *)(wpa8func+8))==0x52822802) ) {
  2511.               /* SetPatch WPA */
  2512.               display->slowwpa8=1;
  2513.             }
  2514.           }
  2515.         }
  2516.  
  2517.         port=CreateMsgPort();
  2518.         if (port) {
  2519.           treq=(struct timerequest *)CreateIORequest(port,
  2520.             sizeof(struct timerequest));
  2521.           if (treq) {
  2522.             if (!OpenDevice(TIMERNAME,UNIT_MICROHZ,
  2523.                (struct IORequest *)treq,0L)) {
  2524.               display->TimerBase=(struct Library *)treq->tr_node.io_Device;
  2525.               CloseDevice((struct IORequest *)treq);
  2526.             }
  2527.             DeleteIORequest((struct IORequest *)treq);
  2528.           }
  2529.           DeleteMsgPort(port);
  2530.         }
  2531.         if (display->TimerBase) {
  2532.  
  2533.           display->CyberGfxBase=OpenLibrary(CYBERGFXNAME,41);
  2534.  
  2535.           if (display->CyberGfxBase) {
  2536.             CyberGfxBase=display->CyberGfxBase;
  2537.             cgxsystemBase=OpenLibrary("cgxsystem.library",41);
  2538.             if (cgxsystemBase) {
  2539.               if ( (cgxsystemBase->lib_Version!=41) ||
  2540.                    (cgxsystemBase->lib_Revision>=20) ) {
  2541.  
  2542.                 display->wlutpa=1;
  2543.  
  2544.               } else {
  2545.  
  2546.                 /* too old cgxsystem.library for WLUTPA */
  2547.                 printf("awin: too old cgxsystem.library for WriteLUTPixelArray(), falling\n"
  2548.                   "back to WritePixelArray(). Please update to minimum\n"
  2549.                   "ftp://ftp.phase5.de/pub/phase5/cgx3/cgxv41_r70a.lha and\n"
  2550.                   "ftp://ftp.phase5.de/pub/phase5/cgx3/cgxsyslib4121.lha\n");
  2551.               }
  2552.               CloseLibrary(cgxsystemBase);
  2553.             }
  2554.  
  2555.             bcmid_tags[0].ti_Tag  = CYBRBIDTG_NominalWidth;
  2556.             bcmid_tags[0].ti_Data = 320;
  2557.             bcmid_tags[1].ti_Tag  = CYBRBIDTG_NominalHeight;
  2558.             bcmid_tags[1].ti_Data = 240;
  2559.             bcmid_tags[2].ti_Tag  = TAG_DONE;
  2560.             display->gfxcard=BestCModeIDTagList(bcmid_tags);
  2561.             if (display->gfxcard!=INVALID_ID) display->gfxcard=1;
  2562.             else display->gfxcard=0;
  2563.  
  2564.             display->cgfx16bit=
  2565.               (awibest16cmodeid(display,320,240)!=INVALID_ID)?1:0;
  2566.  
  2567. #if AW_DEBUG
  2568.             printf("CGFX3+/P96 gfxcard %savailable\n"
  2569.                    "CGFX3+/P96 PIXFMT_RGB16 %savailable\n",
  2570.               display->gfxcard?"":"not ",
  2571.               display->cgfx16bit?"":"not ");
  2572. #endif
  2573.  
  2574. #if AW_CGXVIDEOSUPPORT
  2575.             display->CGXVideoBase=OpenLibrary("cgxvideo.library",41);
  2576. #if AW_DEBUG
  2577.             printf("CGXVideoBase: %lx\n",(ULONG)display->CGXVideoBase);
  2578. #endif
  2579. #endif
  2580.  
  2581.           }
  2582.  
  2583.           display->UtilityBase=OpenLibrary("utility.library",39);
  2584.           if (display->UtilityBase) {
  2585.  
  2586.             display->srcdepth=8;
  2587.  
  2588.             /* build rgb332 palette */
  2589.             for (x=0; x<256; x++) {
  2590.               display->pal332[x]=(x&0xe0)<<16|(x&0x1c)<<11|(x&3)<<6;
  2591.             }
  2592.  
  2593.             display->remap332=malloc(65536);
  2594.             if (display->remap332) {
  2595.  
  2596.               display->DOSBase=OpenLibrary("dos.library",39);
  2597.               if (display->DOSBase) {
  2598.  
  2599.                 /* ... */
  2600.  
  2601.               } else {
  2602.                 printf("awin: could not open dos.library v39\n");
  2603.                 awdeletedisplay(display); display=NULL;
  2604.               }
  2605.             } else {
  2606.               printf("awin: could not allocate 64k memory\n");
  2607.               awdeletedisplay(display); display=NULL;
  2608.             }
  2609.           } else {
  2610.             printf("awin: could not open utility.library v39\n");
  2611.             awdeletedisplay(display); display=NULL;
  2612.           }
  2613.  
  2614.         } else {
  2615.           printf("awin: could not open timer.device\n");
  2616.           awdeletedisplay(display); display=NULL;
  2617.         }
  2618.       } else {
  2619.         printf("awin: could not open intuition.library v39\n");
  2620.         awdeletedisplay(display); display=NULL;
  2621.       }
  2622.     } else {
  2623.       printf("awin: could not open graphics.library v39\n");
  2624.       awdeletedisplay(display); display=NULL;
  2625.     }
  2626.   }
  2627.  
  2628.   return display;
  2629. }
  2630.  
  2631. ULONG awgetvisiblerect(struct awdisplay *display,
  2632.   struct Rectangle *rect) {
  2633.  
  2634.   struct GfxBase *GfxBase;
  2635.   struct IntuitionBase *IntuitionBase;
  2636.   ULONG modeid;
  2637.  
  2638.   if ( (display) && (display->screen) ) {
  2639.     GfxBase=display->GfxBase;
  2640.     IntuitionBase=display->IntuitionBase;
  2641.  
  2642.     modeid=GetVPModeID(&display->screen->ViewPort);
  2643.     if (modeid!=INVALID_ID) {
  2644.       if (QueryOverscan(modeid,rect,OSCAN_TEXT)) {
  2645.         rect->MinX+=display->screen->LeftEdge;
  2646.         rect->MinY+=display->screen->TopEdge;
  2647.         rect->MaxX-=display->screen->LeftEdge;
  2648.         rect->MaxY-=display->screen->TopEdge;
  2649. /*
  2650.         printf("visiblerect: %ld,%ld - %ld,%ld\n",
  2651.           rect->MinX,rect->MinY,rect->MaxX,rect->MaxY);
  2652. */
  2653.         return 1L;
  2654.       }
  2655.     }
  2656.   }
  2657.   return 0L;
  2658. }
  2659.  
  2660. ULONG awgetaspectratio(struct awdisplay *display,ULONG modeid,
  2661.   ULONG *xa,ULONG *ya) {
  2662.  
  2663.   struct GfxBase *GfxBase;
  2664.   struct DisplayInfo dinfo;
  2665.  
  2666.   if (modeid!=INVALID_ID) {
  2667.     GfxBase=display->GfxBase;
  2668.  
  2669.     if (GetDisplayInfoData(NULL,(UBYTE *)&dinfo,
  2670.       sizeof(struct DisplayInfo),DTAG_DISP,modeid)>0) {
  2671.  
  2672.       *xa=dinfo.Resolution.x; *ya=dinfo.Resolution.y;
  2673.       return 1L;
  2674.     }
  2675.   }
  2676.   return 0L;
  2677. }
  2678.  
  2679. ULONG awgetpropertyflags(struct awdisplay *display,ULONG modeid,
  2680.   ULONG *flags) {
  2681.  
  2682.   struct GfxBase *GfxBase;
  2683.   struct DisplayInfo dinfo;
  2684.  
  2685.   if (modeid!=INVALID_ID) {
  2686.     GfxBase=display->GfxBase;
  2687.  
  2688.     if (GetDisplayInfoData(NULL,(UBYTE *)&dinfo,
  2689.       sizeof(struct DisplayInfo),DTAG_DISP,modeid)>0) {
  2690.  
  2691.       *flags=dinfo.PropertyFlags;
  2692.       return 1L;
  2693.     }
  2694.   }
  2695.   return 0L;
  2696. }
  2697.  
  2698. ULONG awgetmaxdepth(struct awdisplay *display,ULONG modeid,
  2699.   ULONG *maxdepth) {
  2700.  
  2701.   struct GfxBase *GfxBase;
  2702.   struct DimensionInfo dinfo;
  2703.  
  2704.   if (modeid!=INVALID_ID) {
  2705.     GfxBase=display->GfxBase;
  2706.  
  2707.     if (GetDisplayInfoData(NULL,(UBYTE *)&dinfo,
  2708.       sizeof(struct DimensionInfo),DTAG_DIMS,modeid)>0) {
  2709.  
  2710.       *maxdepth=dinfo.MaxDepth;
  2711.       return 1L;
  2712.     }
  2713.   }
  2714.   return 0L;
  2715. }
  2716.  
  2717. void awgetwindimension(struct awdisplay *display,
  2718.   ULONG *width,ULONG *height) {
  2719.  
  2720.   struct GfxBase *GfxBase;
  2721.   ULONG xa,ya;
  2722.   float rat;
  2723.  
  2724.   if ( (display) && (display->screen) ) {
  2725.     GfxBase=display->GfxBase;
  2726.  
  2727.     *width=display->origw;
  2728.     *height=display->origh;
  2729.  
  2730.     /* make window (close to) square */
  2731.  
  2732.     xa=22; ya=22;
  2733.     awgetaspectratio(display,GetVPModeID(&display->screen->ViewPort),
  2734.       &xa,&ya);
  2735.     rat=((double)xa)/ya;
  2736.  
  2737.     if (rat<.166) {
  2738.       /* 8:1 */
  2739.       *width *= 2; *height /= 4;
  2740.     } else if (rat<.333) {
  2741.       /* 4:1 */
  2742.       *width *= 2; *height /= 2;
  2743.     } else if (rat<.666) {
  2744.       /* 2:1 */
  2745.       *height /= 2;
  2746.     } else if (rat>6.00) {
  2747.       /* 1:8 */
  2748.       *width /= 4; *height *= 2;
  2749.     } else if (rat>3.00) {
  2750.       /* 1:4 */
  2751.       *width /= 2; *height *= 2;
  2752.     } else if (rat>1.50) {
  2753.       /* 1:2 */
  2754.       *width /= 2;
  2755.     }
  2756.  
  2757.   }
  2758. }
  2759.  
  2760. void awigetscreentype(struct awdisplay *display) {
  2761.  
  2762.   struct GfxBase *GfxBase;
  2763.   struct Library *CyberGfxBase;
  2764.  
  2765.   if ( (display) && (display->screen) ) {
  2766.  
  2767.     GfxBase=display->GfxBase;
  2768.  
  2769.     display->dstdepth=GetBitMapAttr(display->screen->RastPort.BitMap,
  2770.       BMA_DEPTH);
  2771.     display->native=GetBitMapAttr(display->screen->RastPort.BitMap,
  2772.       BMA_FLAGS)&BMF_STANDARD?1:0;
  2773.  
  2774.     if ( (!display->forcenative) && (display->CyberGfxBase) ) {
  2775.       CyberGfxBase=display->CyberGfxBase;
  2776.  
  2777.       if (GetCyberMapAttr(display->screen->RastPort.BitMap,
  2778.         CYBRMATTR_ISCYBERGFX)) {
  2779.  
  2780.         display->native=0; display->cgfx=1;
  2781.         display->dstdepth=GetCyberMapAttr(display->screen->RastPort.BitMap,
  2782.           CYBRMATTR_DEPTH);
  2783.         if (display->dstdepth==0xffffffff) display->dstdepth=0;
  2784.  
  2785.         display->islinearmem=
  2786.           GetCyberMapAttr(
  2787.             display->screen->RastPort.BitMap,
  2788.             CYBRMATTR_ISLINEARMEM);
  2789.  
  2790.         display->isrgb16=
  2791.           (GetCyberMapAttr(
  2792.             display->screen->RastPort.BitMap,
  2793.             CYBRMATTR_PIXFMT)==PIXFMT_RGB16)?1:0;
  2794.       } else {
  2795.         /* is native mode */
  2796.         display->native=1; display->cgfx=0;
  2797.       }
  2798.     }
  2799.  
  2800.     if (display->dstdepth) {
  2801.       if (display->cgfx) {
  2802.         display->truecolor=display->dstdepth>8?1:0;
  2803.       }
  2804.     } else {
  2805.       display->cgfx=0; display->native=0;
  2806.     }
  2807.   }
  2808. }
  2809.  
  2810. ULONG awiopendisplay(struct awdisplay *display) {
  2811.  
  2812.   struct ExecBase *SysBase;
  2813.   struct GfxBase *GfxBase;
  2814.   struct IntuitionBase *IntuitionBase;
  2815.   struct Library *CyberGfxBase;
  2816.   ULONG ret=1,modeid=INVALID_ID,newmodeid,errorcode,
  2817.     cgfxmodeid=0,flags,*modeidpt;
  2818.   ULONG natwidthaligner,natscrwidth;
  2819.   struct Rectangle rect;
  2820.   struct TagItem bcmid_tags[4];
  2821.  
  2822.   if (display) {
  2823.     SysBase=display->SysBase;
  2824.     GfxBase=display->GfxBase;
  2825.     IntuitionBase=display->IntuitionBase;
  2826.  
  2827.     display->fblitptrbm=awallocbm(16,1,2,BMF_CLEAR,NULL,1);
  2828.     if (display->fblitptrbm) {
  2829.       if (display->gfxcard && display->forcenative ) {
  2830.         /* if we have a gfxcard and forcenative is set
  2831.            do NOT think cgfx is fblit */
  2832.         display->fblit=0;
  2833.       } else {
  2834.         display->fblit=TypeOfMem(display->fblitptrbm->Planes[0])&MEMF_CHIP?0:1;
  2835.       }
  2836.  
  2837.       if ( (display->fblit) || (display->slowwpa8) ) {
  2838.         /* c2p needs min 32 */
  2839.         display->widthaligner=32;
  2840.       } else {
  2841.         /* WPA8 needs exactly 16 */
  2842.         /* WCP can take about anything */
  2843.         display->widthaligner=display->v40?32:16;
  2844.       }
  2845.  
  2846.       if (display->windowmode) {
  2847.  
  2848. #if defined(__GNUC__) && defined(AW_PPC)
  2849.         display->screen=LockPubScreen(
  2850.           *display->pubscreen?
  2851.           (ULONG)display->pubscreen:NULL);
  2852. #else
  2853.         display->screen=LockPubScreen(
  2854.           *display->pubscreen?
  2855.           display->pubscreen:NULL);
  2856. #endif
  2857.  
  2858.         /* fallback to default pubscreen if named not found */
  2859.         if ( (*display->pubscreen) && (!display->screen) ) {
  2860.           display->screen=LockPubScreen(NULL);
  2861.         }
  2862.  
  2863.         if (display->screen) {
  2864.  
  2865.           /* if we have the same screen then open on old pos */
  2866.           if (awscreensum(display->screen)==display->prevscreen) {
  2867.  
  2868.             display->width=display->prevwidth;
  2869.             display->height=display->prevheight;
  2870.             display->width_align=awalign(display->width,display->widthaligner);
  2871.             display->pixperrow=display->width_align;
  2872.             display->scrwidth=display->width_align;
  2873.  
  2874.             /* display->left and display->top are ok already */
  2875.  
  2876.           } else {
  2877.  
  2878.             awgetwindimension(display,&display->width,&display->height);
  2879.             display->width_align=awalign(display->width,display->widthaligner);
  2880.             display->pixperrow=display->width_align;
  2881.             display->scrwidth=display->width_align;
  2882.  
  2883.             if (display->abspos) {
  2884.  
  2885.               /* absolute position given */
  2886.               display->left=display->xdisp;
  2887.               display->top=display->ydisp;
  2888.  
  2889.             } else {
  2890.  
  2891.               /* center the window */
  2892.               rect.MinX=0; rect.MinY=0;
  2893.               rect.MaxX=display->screen->Width;
  2894.               rect.MaxY=display->screen->Height;
  2895.               awgetvisiblerect(display,&rect);
  2896.  
  2897.               display->left=(rect.MaxX-rect.MinX-
  2898.                 awtowindoww(display,display->width))/2+display->xdisp;
  2899.               display->top=(rect.MaxY-rect.MinY-
  2900.                 awtowindowh(display,display->height))/2+display->ydisp;
  2901.             }
  2902.           }
  2903.  
  2904.           display->window=OpenWindowTags(0L,
  2905.             WA_CustomScreen,(ULONG)display->screen,
  2906.             WA_Left,display->left,
  2907.             WA_Top,display->top,
  2908.             WA_InnerWidth,display->width,
  2909.             WA_InnerHeight,display->height,
  2910.             WA_AutoAdjust,1,
  2911.             WA_MinWidth,awtowindoww(display,AW_MINWIDTH),
  2912.             WA_MaxWidth,awtowindoww(display,AW_MAXWIDTH),
  2913.             WA_MinHeight,awtowindowh(display,AW_MINHEIGHT),
  2914.             WA_MaxHeight,awtowindowh(display,AW_MAXHEIGHT),
  2915.             *display->title?WA_Title:TAG_IGNORE,(ULONG)display->title,
  2916.             WA_Flags,WFLG_ACTIVATE|WFLG_CLOSEGADGET|WFLG_DRAGBAR|
  2917.               WFLG_DEPTHGADGET|WFLG_SIZEGADGET|WFLG_RMBTRAP|
  2918.               WFLG_NOCAREREFRESH|WFLG_SIZEBRIGHT,
  2919.             WA_IDCMP,AW_WWIDCMPFLAGS|display->idcmpflags,
  2920.             TAG_DONE);
  2921.  
  2922.           if (!display->window) {
  2923.             AW_VPRINT("awin: could not open window\n");
  2924.             awclosedisplay(display); ret=0;
  2925.           }
  2926.  
  2927.         } else {
  2928.           AW_VPRINT("awin: could not lock pubscreen\n");
  2929.           awclosedisplay(display); ret=0;
  2930.         }
  2931.  
  2932.       } else {
  2933.  
  2934.         /* screen mode */
  2935.  
  2936.         if ( (display->srcdepth==16) && (display->usehamf) ) {
  2937.           display->doham=1;
  2938.         } else {
  2939.           display->doham=0;
  2940.         }
  2941.  
  2942.         display->width=display->origw;
  2943.         display->height=display->origh;
  2944.  
  2945.         /* NATIVE: width is multiple of 64 (AGA) or 32 (OCS/ECS) */
  2946.         natwidthaligner=16<<
  2947.           display->GfxBase->bwshifts[display->GfxBase->MemType];
  2948.         if (natwidthaligner<32) natwidthaligner=32;
  2949.         natscrwidth=awalign(display->width,natwidthaligner);
  2950.         if (display->doham) natscrwidth*=2;
  2951.  
  2952.         modeidpt=(display->srcdepth==16)?&display->modeid16:&display->modeid8;
  2953.  
  2954. /*        if ( (!display->modeid16) &&*/
  2955.         if ( (!*modeidpt) &&
  2956.              (!display->forcenative) &&
  2957.              (display->CyberGfxBase) ) {
  2958.           CyberGfxBase=display->CyberGfxBase;
  2959.  
  2960.           bcmid_tags[0].ti_Tag  = CYBRBIDTG_NominalWidth;
  2961.           bcmid_tags[0].ti_Data = awalign(display->width,32);
  2962.           bcmid_tags[1].ti_Tag  = CYBRBIDTG_NominalHeight;
  2963.           bcmid_tags[1].ti_Data = display->height;
  2964.           bcmid_tags[2].ti_Tag  = CYBRBIDTG_Depth;
  2965.           bcmid_tags[2].ti_Data = display->cgfx16bitf?display->srcdepth:8;
  2966.           bcmid_tags[3].ti_Tag  = TAG_DONE;
  2967.           modeid=BestCModeIDTagList(bcmid_tags);
  2968.         }
  2969.  
  2970.         if ( (*modeidpt) && (*modeidpt!=INVALID_ID) ) {
  2971.           modeid=*modeidpt;
  2972.         } else {
  2973.  
  2974.           if (modeid==INVALID_ID) {
  2975.  
  2976.             /* get native default monitor for widht/height
  2977.                (asking HAM will filter out foreign monitors) */
  2978.             modeid=BestModeID(
  2979.               BIDTAG_DIPFMustHave,
  2980.                 (display->nodbuffer?0:DIPF_IS_DBUFFER)|
  2981.                 DIPF_IS_HAM,
  2982.               BIDTAG_NominalWidth,natscrwidth,
  2983.               BIDTAG_NominalHeight,display->height,
  2984.               BIDTAG_Depth,1,
  2985.               TAG_DONE);
  2986.             if (modeid==INVALID_ID) modeid=0;
  2987.             else modeid&=MONITOR_ID_MASK,
  2988.  
  2989.             modeid=BestModeID(
  2990.               BIDTAG_MonitorID,modeid,
  2991.               BIDTAG_DIPFMustHave,
  2992.                 (display->nodbuffer?0:DIPF_IS_DBUFFER)|
  2993.                 (display->doham?DIPF_IS_HAM:0),
  2994.               BIDTAG_NominalWidth,natscrwidth,
  2995.               BIDTAG_NominalHeight,display->height,
  2996.               BIDTAG_Depth,display->doham?6:8,
  2997.               TAG_DONE);
  2998.           }
  2999.         }
  3000.  
  3001.         if (modeid!=INVALID_ID) {
  3002.  
  3003.           if ( (!display->forcenative) && (display->CyberGfxBase) ) {
  3004.             CyberGfxBase=display->CyberGfxBase;
  3005.             if (IsCyberModeID(modeid)) {
  3006.               cgfxmodeid=1;
  3007.  
  3008.               if ( (display->srcdepth==16) &&
  3009.                    (display->cgfx16bitf) ) {
  3010.  
  3011.                 if (GetCyberIDAttr(
  3012.                      CYBRIDATTR_PIXFMT,modeid)!=PIXFMT_RGB16) {
  3013.  
  3014.                   newmodeid=awibest16cmodeid(
  3015.                     display,
  3016.                     awalign(display->width,32),
  3017.                     display->height);
  3018.                   if (newmodeid!=INVALID_ID) {
  3019.                     modeid=newmodeid;
  3020.                   }
  3021.                 }
  3022.               }
  3023.             }
  3024.           }
  3025.  
  3026. #if AW_DEBUG
  3027.           printf("cgfxmodeid: %ld modeid: 0x%lx (%lu)\n",
  3028.             cgfxmodeid,modeid,modeid);
  3029. #endif
  3030.  
  3031.           if (cgfxmodeid) {
  3032.  
  3033.             /* CGFX: width is multiple of 32 */
  3034.             display->widthaligner=32;
  3035.  
  3036.             display->width_align=awalign(display->width,display->widthaligner);
  3037.             display->scrwidth=display->width_align;
  3038.  
  3039.             display->screen=OpenScreenTags(NULL,
  3040.               SA_Width,display->scrwidth,
  3041.               SA_Height,display->height,
  3042.               SA_Depth,display->cgfx16bitf?display->srcdepth:8,
  3043.               *display->title?SA_Title:TAG_IGNORE,(ULONG)display->title,
  3044.               SA_ShowTitle,0,
  3045.               SA_Quiet,1,
  3046.               SA_Type,CUSTOMSCREEN,
  3047.               SA_DisplayID,modeid,
  3048.               SA_ErrorCode,(ULONG)&errorcode,
  3049.               TAG_DONE);
  3050.           } else {
  3051.  
  3052.             flags=0L;
  3053.             awgetpropertyflags(display,modeid,&flags);
  3054.  
  3055.             display->widthaligner=natwidthaligner;
  3056.             display->width_align=awalign(display->width,display->widthaligner);
  3057.  
  3058.             if ( (flags&DIPF_IS_HAM) &&
  3059.                  display->doham) {
  3060.               display->scrwidth=display->width_align*2;
  3061.             } else {
  3062.               display->scrwidth=display->width_align;
  3063.             }
  3064.  
  3065.             display->c2pplanes[0]=
  3066.               awiallocbitmap(
  3067.                 display,
  3068.                 &display->c2pbitmap[0],
  3069.                 display->scrwidth,
  3070.                 display->height,
  3071.                 (flags&DIPF_IS_HAM)&&display->doham?6:8,
  3072.                 MEMF_CHIP|MEMF_CLEAR);
  3073.  
  3074.             if (!display->c2pplanes[0]) {
  3075.               AW_VPRINT("awin: could not allocate bitmap[0] chip memory\n");
  3076.               awclosedisplay(display); return 0L;
  3077.             }
  3078.  
  3079.             display->screen=OpenScreenTags(NULL,
  3080.               SA_Width,display->scrwidth,
  3081.               SA_Height,display->height,
  3082.               SA_Depth,(flags&DIPF_IS_HAM)&&display->doham?6:8,
  3083.               SA_BitMap,(ULONG)&display->c2pbitmap[0],
  3084.               *display->title?SA_Title:TAG_IGNORE,(ULONG)display->title,
  3085.               SA_ShowTitle,0,
  3086.               SA_Quiet,1,
  3087.               SA_Type,CUSTOMSCREEN,
  3088.               SA_DisplayID,modeid,
  3089.               SA_AutoScroll,1,
  3090.               SA_ErrorCode,(ULONG)&errorcode,
  3091.               display->IntuitionBase->LibNode.lib_Version>=40 ?
  3092.                 SA_MinimizeISG:TAG_IGNORE,1,
  3093.               TAG_DONE);
  3094.           }
  3095.  
  3096.           if (display->screen) {
  3097.  
  3098.             display->pixperrow=display->width_align;
  3099.  
  3100.             flags=0L;
  3101.             awgetpropertyflags(display,
  3102.               GetVPModeID(&display->screen->ViewPort),&flags);
  3103.  
  3104.             if (!display->nodbuffer) {
  3105.               display->dbuffer=flags&DIPF_IS_DBUFFER?1:0;
  3106.             }
  3107.  
  3108. #if AW_DEBUG
  3109.             printf("dbuffer: %ld\n",
  3110.               display->dbuffer);
  3111. #endif
  3112.  
  3113.             if (display->dbuffer) {
  3114.  
  3115.               if (!cgfxmodeid) {
  3116.  
  3117.                 display->c2pplanes[1]=
  3118.                   awiallocbitmap(
  3119.                     display,
  3120.                     &display->c2pbitmap[1],
  3121.                     display->scrwidth,
  3122.                     display->height,
  3123.                     (flags&DIPF_IS_HAM)&&display->doham?6:8,
  3124.                     MEMF_CHIP);
  3125.  
  3126.                 if (!display->c2pplanes[1]) {
  3127.                   AW_VPRINT("awin: could not allocate bitmap[1] chip memory\n");
  3128.                   awclosedisplay(display); return 0L;
  3129.                 }
  3130.  
  3131.               }
  3132.  
  3133.               display->sbports[AW_DISPPORT]=CreateMsgPort();
  3134.               if (display->waitswap) {
  3135.                 display->sbports[AW_WRITEPORT]=CreateMsgPort();
  3136.               } else {
  3137.                 display->sbports[AW_WRITEPORT]=
  3138.                   display->sbports[AW_DISPPORT];
  3139.               }
  3140.  
  3141.               if ( (display->sbports[AW_DISPPORT]) &&
  3142.                    (display->sbports[AW_WRITEPORT]) ) {
  3143.  
  3144. #if defined(__GNUC__) && defined(AW_PPC)
  3145.                 display->sbuf[0]=AllocScreenBuffer(
  3146.                   display->screen,cgfxmodeid?NULL:(ULONG)&display->c2pbitmap[0],
  3147.                   cgfxmodeid?SB_SCREEN_BITMAP:0L);
  3148.                 display->sbuf[1]=AllocScreenBuffer(
  3149.                   display->screen,cgfxmodeid?NULL:(ULONG)&display->c2pbitmap[1],
  3150.                   0L);
  3151. #else
  3152.                 display->sbuf[0]=AllocScreenBuffer(
  3153.                   display->screen,cgfxmodeid?NULL:&display->c2pbitmap[0],
  3154.                   cgfxmodeid?SB_SCREEN_BITMAP:0L);
  3155.                 display->sbuf[1]=AllocScreenBuffer(
  3156.                   display->screen,cgfxmodeid?NULL:&display->c2pbitmap[1],
  3157.                   0L);
  3158. #endif
  3159.  
  3160.                 if ( (display->sbuf[0]) && (display->sbuf[1]) ) {
  3161.  
  3162.                   display->sbuf[0]->sb_DBufInfo->
  3163.                     dbi_SafeMessage.mn_ReplyPort=display->sbports[AW_WRITEPORT];
  3164.                   display->sbuf[1]->sb_DBufInfo->
  3165.                     dbi_SafeMessage.mn_ReplyPort=display->sbports[AW_WRITEPORT];
  3166.  
  3167.                   if (display->waitswap) {
  3168.                     display->sbuf[0]->sb_DBufInfo->
  3169.                       dbi_DispMessage.mn_ReplyPort=display->sbports[AW_DISPPORT];
  3170.                     display->sbuf[1]->sb_DBufInfo->
  3171.                       dbi_DispMessage.mn_ReplyPort=display->sbports[AW_DISPPORT];
  3172.                   }
  3173.  
  3174.                   display->safetochange=1;
  3175.                   display->safetowrite=1;
  3176.                   display->curbuffer=1;
  3177.  
  3178.                 } else {
  3179.                   AW_VPRINT("awin: could not allocate dbuffer screenbuffers\n");
  3180.                   awclosedisplay(display); ret=0;
  3181.                 }
  3182.  
  3183.               } else {
  3184.                 AW_VPRINT("awin: could not allocate dbuffer msgports\n");
  3185.                 awclosedisplay(display); ret=0;
  3186.               }
  3187.             } else {
  3188.  
  3189.               display->curbuffer=0;  /* for c2p */
  3190.  
  3191.             }
  3192.  
  3193.             if (ret) {
  3194.               display->pointerobject=NewObject(
  3195.                 NULL,POINTERCLASS,
  3196.                 POINTERA_BitMap,(ULONG)display->fblitptrbm,
  3197.                 POINTERA_WordWidth,1,
  3198.                 TAG_DONE);
  3199.  
  3200.               display->window=OpenWindowTags(0L,
  3201.                 WA_CustomScreen,(ULONG)display->screen,
  3202.                 display->pointerobject?WA_Pointer:TAG_IGNORE,
  3203.                   (ULONG)display->pointerobject,
  3204.                 WA_Left,0,
  3205.                 WA_Top,0,
  3206.                 WA_Width,display->screen->Width,
  3207.                 WA_Height,display->screen->Height,
  3208.                 WA_Flags,WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_NOCAREREFRESH|
  3209.                   WFLG_BACKDROP|WFLG_BORDERLESS,
  3210.                 WA_IDCMP,AW_SWIDCMPFLAGS|display->idcmpflags,
  3211.                 TAG_DONE);
  3212.  
  3213.               if (!display->window) {
  3214.                 AW_VPRINT("awin: could not open window\n");
  3215.                 awclosedisplay(display); ret=0;
  3216.               }
  3217.             }
  3218.           } else {
  3219.             if (display->debug>=AWD_VERBOSE) {
  3220.               printf("awin: OpenScreenTagList failed: ");
  3221.               switch (errorcode) {
  3222.                 case OSERR_NOMONITOR:
  3223.                   puts("monitor for display mode not available");
  3224.                   break;
  3225.                 case OSERR_NOCHIPS:
  3226.                   puts("you need newer custom chips for display mode");
  3227.                   break;
  3228.                 case OSERR_NOMEM:
  3229.                   puts("couldn't get normal memory");
  3230.                   break;
  3231.                 case OSERR_NOCHIPMEM:
  3232.                   puts("couldn't get chip memory");
  3233.                   break;
  3234.                 case OSERR_PUBNOTUNIQUE:
  3235.                   puts("public screen name already used");
  3236.                   break;
  3237.                 case OSERR_UNKNOWNMODE:
  3238.                   puts("don't recognize display mode requested");
  3239.                   break;
  3240.                 case OSERR_TOODEEP:
  3241.                   puts("screen too deep to be displayed on this hw");
  3242.                   break;
  3243.                 case OSERR_ATTACHFAIL:
  3244.                   puts("illegal attachment of screens was requested");
  3245.                   break;
  3246.               }
  3247.             }
  3248.             awclosedisplay(display); ret=0;
  3249.           }
  3250.  
  3251.         } else {
  3252.           if (display->debug>=AWD_VERBOSE) {
  3253.             printf("awin: could not find modeid for %ldx%ldx%ld.\n",
  3254.               display->scrwidth,display->height,
  3255.               display->cgfx16bitf?display->srcdepth:8);
  3256.           }
  3257.           awclosedisplay(display); ret=0;
  3258.         }
  3259.       }
  3260.  
  3261.       if (ret) {
  3262.         /* (screen &) window open etc */
  3263.  
  3264.         awigetscreentype(display);
  3265.  
  3266.         if (display->dstdepth) {
  3267.  
  3268.           /* debug
  3269.           display->native=0; display->cgfx=1;
  3270.           display->truecolor=1;
  3271.           */
  3272.  
  3273.           if ( (!display->native) && (!display->cgfx) ) {
  3274.             if (!display->windowmode) {
  3275.               AW_VPRINT("awin: neither native nor gfxcard screen\n"
  3276.                 "falling back to native mode\n");
  3277.             }
  3278.             display->native=1;
  3279.           }
  3280.  
  3281.           if (!display->windowmode) {
  3282.  
  3283.             display->isham6=0;
  3284.             if (display->doham) {
  3285.               if ( (flags&DIPF_IS_HAM) && (display->dstdepth==6) ) {
  3286.                 display->isham6=1;
  3287.               } else {
  3288.                 AW_VPRINT("awin: bad ham6 screen\n");
  3289. #if AW_DEBUG
  3290.                 printf("flags&DIPF_IS_HAM: %ld display->dstdepth: %ld\n",
  3291.                   flags&DIPF_IS_HAM,display->dstdepth);
  3292. #endif
  3293.                 awclosedisplay(display); return 0;
  3294.               }
  3295.             }
  3296.  
  3297.             if ( (display->screen->Width!=display->scrwidth) ||
  3298.                  (display->screen->Height!=display->height) ) {
  3299.               AW_VPRINT("awin: screen dimensions don't match!\n");
  3300.               awclosedisplay(display); return 0L;
  3301.             }
  3302.             if ( (!display->isham6) &&
  3303.                  (display->srcdepth==8) &&
  3304.                  (display->dstdepth!=display->srcdepth) ) {
  3305.               AW_VPRINT("awin: screen depth doesn't match!\n");
  3306.               awclosedisplay(display); return 0L;
  3307.             }
  3308.           }
  3309.  
  3310. #if AW_DEBUG
  3311. /*
  3312.           printf("isham6: %lu\n",display->isham6);
  3313. */
  3314. #endif
  3315.  
  3316.           awremap(display);
  3317.  
  3318.           if (awreopen(display)) {
  3319.             if ( (display->windowmode) &&
  3320.                  (display->screen) &&
  3321.                  (awscreensum(display->screen)!=
  3322.                  display->prevscreen) ) {
  3323.  
  3324.               ScreenToFront(display->screen);
  3325.             }
  3326.  
  3327.             /* ... */
  3328.  
  3329.           } else ret=0;
  3330.  
  3331.         } else {
  3332.           AW_VPRINT("awin: fucked up screen depth\n");
  3333.           awclosedisplay(display); ret=0;
  3334.         }
  3335.       }
  3336.  
  3337.     } else {
  3338.       AW_VPRINT("awin: could not allocate fblit bitmap\n");
  3339.       awclosedisplay(display); ret=0;
  3340.     }
  3341.   }
  3342.   return ret;
  3343. }
  3344.  
  3345. ULONG awsetdisplaysize(struct awdisplay *display,
  3346.   ULONG width,ULONG height) {
  3347.  
  3348.   ULONG ret=0;
  3349.  
  3350.   if (display) {
  3351.     if (display->screen) {
  3352.       awclosedisplay(display);
  3353.  
  3354.       display->origw=width;
  3355.       display->origh=height;
  3356.       display->prevscreen=0;
  3357.  
  3358.       ret=awiopendisplay(display);
  3359.       if (!ret) {
  3360.         /* try the other mode (fallback) */
  3361.         display->windowmode ^= 1;
  3362.         ret=awiopendisplay(display);
  3363.         if (!ret) display->windowmode ^= 1;
  3364.       }
  3365.     } else {
  3366.       display->origw=width;
  3367.       display->origh=height;
  3368.       display->prevscreen=0;
  3369.     }
  3370.   }
  3371.   return ret;
  3372. }
  3373.  
  3374. ULONG awsetflags(struct awdisplay *display,ULONG flags) {
  3375.   ULONG ret=0;
  3376.   if (display) {
  3377.  
  3378.     /* build oldflags */
  3379.     if (display->windowmode) ret|=AWODAF_INITWINDOW;
  3380.     if (display->dontupdateinactive) ret|=AWODAF_DONTUPDATEINA;
  3381.     if (display->nodbuffer) ret|=AWODAF_NODBUFFER;
  3382.     if (display->forcenative) ret|=AWODAF_FORCENATIVE;
  3383.     if (display->directdraw) ret|=AWODAF_DIRECTDRAW;
  3384.     if (display->useham) ret|=AWODAF_USEHAM;
  3385.     if (display->waitswap) ret|=AWODAF_WAITSWAP;
  3386.     if (display->usecgxvideo) ret|=AWODAF_USECGXVIDEO;
  3387.     if (display->useargb16) ret|=AWODAF_USEARGB16;
  3388.     if (display->abspos) ret|=AWODAF_ABSPOS;
  3389.  
  3390.  
  3391.     /* force flags sensible */
  3392.     if (flags&AWODAF_FORCENATIVE) flags&=~AWODAF_DIRECTDRAW;
  3393.  
  3394.     /* set flags in struct display */
  3395.     display->windowmode=
  3396.       flags&AWODAF_INITWINDOW?1:0;
  3397.  
  3398.     display->dontupdateinactive=
  3399.       flags&AWODAF_DONTUPDATEINA?1:0;
  3400.  
  3401.     display->nodbuffer=
  3402.       flags&AWODAF_NODBUFFER?1:0;
  3403.  
  3404.     display->forcenative=
  3405.       flags&AWODAF_FORCENATIVE?1:0;
  3406.  
  3407.     display->directdraw=
  3408.       flags&AWODAF_DIRECTDRAW?1:0;
  3409.  
  3410.     display->useham=
  3411.       flags&AWODAF_USEHAM?1:0;
  3412.  
  3413.     display->waitswap=
  3414.       flags&AWODAF_WAITSWAP?1:0;
  3415.  
  3416.     display->usecgxvideo=
  3417.       flags&AWODAF_USECGXVIDEO?1:0;
  3418.  
  3419.     display->useargb16=
  3420.       flags&AWODAF_USEARGB16?1:0;
  3421.  
  3422.     display->abspos=
  3423.       flags&AWODAF_ABSPOS?1:0;
  3424.  
  3425.     if (display->gfxcard && (!display->forcenative)) {
  3426.       display->usehamf=0;
  3427.     } else {
  3428.       display->usehamf=display->useham;
  3429.     }
  3430.  
  3431.     if (display->forcenative) {
  3432.       display->cgfx16bitf=0;
  3433.     } else {
  3434.       display->cgfx16bitf=display->cgfx16bit;
  3435.     }
  3436.  
  3437.   }
  3438.   return ret;
  3439. }
  3440.  
  3441. ULONG awopendisplay(struct awdisplay *display,
  3442.   struct awodargs *odargs) {
  3443.  
  3444.   ULONG ret=1;
  3445.  
  3446.   if ( (display) && (!display->window) ) {
  3447.  
  3448.     (void)awsetflags(display,odargs->flags);
  3449.  
  3450.     awivalidatedim(display,&odargs->width,&odargs->height);
  3451.     awivalidatemodeid(display,&odargs->modeid8,
  3452.       odargs->width,odargs->height,8);
  3453.     awivalidatemodeid(display,&odargs->modeid16,
  3454.       odargs->width,odargs->height,16);
  3455.  
  3456.     if (odargs->modeid8) {
  3457.       display->modeid8=odargs->modeid8;
  3458.     }
  3459.     if (odargs->modeid16) {
  3460.       display->modeid16=odargs->modeid16;
  3461.     }
  3462.  
  3463.     if (odargs->title) {
  3464.       strncpy(display->title,odargs->title,79);
  3465.       display->title[79]=0;
  3466.     } else *display->title=0;
  3467.  
  3468.     if (odargs->pubscreen) {
  3469.       strncpy(display->pubscreen,odargs->pubscreen,MAXPUBSCREENNAME);
  3470.       display->pubscreen[MAXPUBSCREENNAME]=0;
  3471.     } else *display->pubscreen=0;
  3472.  
  3473.     display->origw=odargs->width;
  3474.     display->origh=odargs->height;
  3475.  
  3476.     if (display->windowmode) {
  3477.       display->xdisp=odargs->x;
  3478.       display->ydisp=odargs->y;
  3479.     }
  3480.  
  3481. #if 0
  3482.     ret=awiopendisplay(display);
  3483.     if (!ret) {
  3484.       /* try the other mode (fallback) */
  3485.       display->windowmode ^= 1;
  3486.       ret=awiopendisplay(display);
  3487.       if (!ret) display->windowmode ^= 1;
  3488.     }
  3489. #endif
  3490.  
  3491.   }
  3492.   return ret;
  3493. }
  3494.  
  3495. ULONG awhandleinput(struct awdisplay *display) {
  3496.   ULONG ret=1,action,origw,origh;
  3497.   LONG quit=0,doreopen=0,space=0,w=0,s=0,tab=0,p=0,m=0;
  3498.   LONG xdif,ydif;
  3499.   struct ExecBase *SysBase=display->SysBase;
  3500.   struct GfxBase *GfxBase=display->GfxBase;
  3501.   struct IntuitionBase *IntuitionBase=display->IntuitionBase;
  3502.   struct IntuiMessage *msg,mcopy;
  3503.  
  3504.   /* indicate quit if there is no window */
  3505.   if ( (!display) || (!display->window) ) return 0;
  3506.  
  3507.   while ( (msg=(struct IntuiMessage *)
  3508.     GetMsg(display->window->UserPort)) ) {
  3509.     if (msg->Class==IDCMP_SIZEVERIFY) {
  3510.       display->stoprender=1;
  3511.       /* make sure buffers are flushed */
  3512.       while (display->rendering);
  3513.       if (display->native) WaitBlit();
  3514.     }
  3515.     memcpy(&mcopy,msg,sizeof(struct IntuiMessage));
  3516.     ReplyMsg((struct Message *)msg);
  3517.  
  3518.     if ( (display->idcmphook) &&
  3519.          (mcopy.Class & display->idcmpflags) ) {
  3520.  
  3521.       action=display->idcmphook(&mcopy);
  3522.  
  3523.       if (action!=AWIDHA_NOP) {
  3524.         AW_DPRINT("awin: display->idcmphook action not implemented yet\n");
  3525.       }
  3526.     }
  3527.  
  3528.     switch (mcopy.Class) {
  3529.       case IDCMP_CLOSEWINDOW:
  3530.         quit=1;
  3531.         break;
  3532.       case IDCMP_NEWSIZE:
  3533.         doreopen=1;
  3534.         break;
  3535.       case IDCMP_RAWKEY:
  3536.         switch (mcopy.Code) {
  3537.           case 0x45:
  3538.           case 0x10:
  3539.             /* Q / ESC */
  3540.             quit=1;
  3541.             break;
  3542.           case 0x40:
  3543.             /* space */
  3544.             space=1;
  3545.             break;
  3546.           case 0x11:
  3547.             /* W */
  3548.             w=1;
  3549.             break;
  3550.           case 0x21:
  3551.             /* S */
  3552.             s=1;
  3553.             break;
  3554.           case 0x42:
  3555.             /* TAB */
  3556.             tab=1;
  3557.             break;
  3558.           case 0x19:
  3559.             /* P */
  3560.             p=1;
  3561.             break;
  3562.           case 0x37:
  3563.             /* M */
  3564.             m=1;
  3565.             break;
  3566.         }
  3567.         /*
  3568.         printf("rawkey: %ld ",mcopy.Code);
  3569.         printf("qualifier: 0x%lx\n",mcopy.Qualifier);
  3570.         */
  3571.         break;
  3572.  
  3573.       case IDCMP_VANILLAKEY:
  3574.         switch (mcopy.Code) {
  3575.           case 'q':
  3576.           case 'Q':
  3577.           case  27: quit=1; break;
  3578.           case ' ': space=1; break;
  3579.           case 'w':
  3580.           case 'W': w=1; break;
  3581.           case 's':
  3582.           case 'S': s=1; break;
  3583.           case   9: tab=1; break;
  3584.           case 'p':
  3585.           case 'P': p=1; break;
  3586.           case 'm':
  3587.           case 'M': m=1; break;
  3588.         }
  3589.         break;
  3590.  
  3591.       case IDCMP_INACTIVEWINDOW:
  3592.         if (display->dontupdateinactive) {
  3593.           display->stoprender=1;
  3594.         }
  3595.         break;
  3596.       case IDCMP_ACTIVEWINDOW:
  3597.         if (display->dontupdateinactive) {
  3598.           display->stoprender=0;
  3599.         }
  3600.         break;
  3601.  
  3602.     }
  3603.   }
  3604.  
  3605.   if (quit) {
  3606.  
  3607.     /* quit */
  3608.  
  3609.     ret=0;
  3610.  
  3611.   } else if (doreopen) {
  3612.  
  3613.     /* handle window resize */
  3614.  
  3615.     if (awreopen(display)) {
  3616.       display->stoprender=0;
  3617.     } else ret=0;
  3618.  
  3619.   } else if (space) {
  3620.  
  3621.     if (display->windowmode) {
  3622.  
  3623.       awgetwindimension(display,&origw,&origh);
  3624.       xdif=display->width-origw; ydif=display->height-origh;
  3625.  
  3626.       if ( xdif || ydif ) {
  3627.  
  3628.         display->stoprender=1;   /* kindof hack, relies on IDCMP_NEWSIZE */
  3629.  
  3630.         if (display->abspos) {
  3631.  
  3632.           /* readjust window size */
  3633.  
  3634.           ChangeWindowBox(display->window,
  3635.             display->window->LeftEdge,display->window->TopEdge,
  3636.             awtowindoww(display,origw),awtowindowh(display,origh));
  3637.         } else {
  3638.  
  3639.           /* readjust window size/position */
  3640.  
  3641.           ChangeWindowBox(display->window,
  3642.             display->window->LeftEdge+xdif/2,display->window->TopEdge+ydif/2,
  3643.             awtowindoww(display,origw),awtowindowh(display,origh));
  3644.         }
  3645.       }
  3646.     }
  3647.  
  3648.   } else if (w) {
  3649.  
  3650.    /* goto window mode, if not already */
  3651.  
  3652.    if (!display->windowmode) {
  3653.      awclosedisplay(display);
  3654.      display->windowmode=1;
  3655.      ret=awiopendisplay(display);
  3656.      if (!ret) {
  3657.        /* retry screen mode */
  3658.        display->windowmode=0;
  3659.        ret=awiopendisplay(display);
  3660.        if (!ret) display->windowmode ^= 1;
  3661.      }
  3662.      display->stoprender=0;
  3663.    }
  3664.  
  3665.   } else if (s) {
  3666.  
  3667.     /* goto screen mode, if not already */
  3668.  
  3669.     if (display->windowmode) {
  3670.       awclosedisplay(display);
  3671.       display->windowmode=0;
  3672.       ret=awiopendisplay(display);
  3673.       if (!ret) {
  3674.         /* retry window mode */
  3675.         display->windowmode=1;
  3676.         ret=awiopendisplay(display);
  3677.         if (!ret) display->windowmode ^= 1;
  3678.       }
  3679.       display->stoprender=0;
  3680.     }
  3681.  
  3682.   } else if (tab) {
  3683.  
  3684.     /* toggle mode */
  3685.  
  3686.     awclosedisplay(display);
  3687.     display->windowmode ^= 1;
  3688.     ret=awiopendisplay(display);
  3689.     if (!ret) {
  3690.       /* retry the original mode */
  3691.       display->windowmode ^= 1;
  3692.       ret=awiopendisplay(display);
  3693.       if (!ret) display->windowmode ^= 1;
  3694.     }
  3695.     display->stoprender=0;
  3696.  
  3697.   } else if (p) {
  3698.  
  3699.     /* toggle pause... */
  3700.  
  3701.     display->stoprender ^= 1;
  3702.  
  3703.   } else if (m) {
  3704.  
  3705.     /* screenmode req... */
  3706.  
  3707.     awclosedisplay(display);
  3708.  
  3709.     if (awscreenmodereq(
  3710.       display,
  3711.       (display->srcdepth==16)?&display->modeid16:&display->modeid8,
  3712.       display->srcdepth,
  3713.       &display->width,
  3714.       &display->height,
  3715.       1)) {
  3716.  
  3717.       display->origw=display->width;
  3718.       display->origh=display->height;
  3719.       display->prevscreen=0;
  3720.     }
  3721.  
  3722.     ret=awiopendisplay(display);
  3723.     if (!ret) {
  3724.       /* try the other mode (fallback) */
  3725.       display->windowmode ^= 1;
  3726.       ret=awiopendisplay(display);
  3727.       if (!ret) display->windowmode ^= 1;
  3728.     }
  3729.  
  3730.     display->stoprender=0;
  3731.  
  3732.   }
  3733.  
  3734.   return ret;
  3735. }
  3736.  
  3737. /* LUT8 -> LUT8 scale and remap routines */
  3738.  
  3739. /* LUT8 scale chunky buffer, 24.8 precision
  3740. */
  3741.  
  3742. void awscalechunky8(struct awdisplay *display,
  3743.   struct awchunky *chunky) {
  3744.  
  3745. #if AW_USEREMAPSCALE68K
  3746.  
  3747. #if AW_SCALEDEBUG
  3748.   display->height--;
  3749. #endif
  3750.  
  3751.   awddscalech68k8(
  3752.     chunky->framebuffer,
  3753.     display->framebuffer,
  3754.     chunky->width,
  3755.     chunky->height,
  3756.     display->width,
  3757.     display->height,
  3758.     display->width_align,
  3759.     display->pixperrow);
  3760.  
  3761. #if AW_SCALEDEBUG
  3762.   display->height++;
  3763. #endif
  3764. }
  3765.  
  3766. #else
  3767.  
  3768.   ULONG x,y,xpo,ypo,xadd,yadd,*t,*d,modulo;
  3769.  
  3770. #if AW_SCALEDEBUG
  3771.   display->height--;
  3772. #endif
  3773.  
  3774.   modulo=display->pixperrow-display->width_align;
  3775.  
  3776.   xadd=(chunky->width<<8)/display->width;
  3777.   yadd=(chunky->height<<8)/display->height;
  3778.  
  3779.   if (xadd!=256) {
  3780.  
  3781.     for (ypo=0, d=(ULONG *)display->framebuffer, y=0; y<display->height;
  3782.       d=(ULONG *)((ULONG)d+modulo), ypo+=yadd, y++)
  3783.       for (xpo=chunky->width_align*(ypo&0xffffff00), x=0;
  3784.         x<display->width_align; x+=16)
  3785.  
  3786.         *d++=chunky->framebuffer[xpo>>8]<<24|
  3787.           chunky->framebuffer[(xpo+=xadd)>>8]<<16|
  3788.           chunky->framebuffer[(xpo+=xadd)>>8]<<8|
  3789.           chunky->framebuffer[(xpo+=xadd)>>8],
  3790.  
  3791.         *d++=chunky->framebuffer[(xpo+=xadd)>>8]<<24|
  3792.           chunky->framebuffer[(xpo+=xadd)>>8]<<16|
  3793.           chunky->framebuffer[(xpo+=xadd)>>8]<<8|
  3794.           chunky->framebuffer[(xpo+=xadd)>>8],
  3795.  
  3796.         *d++=chunky->framebuffer[(xpo+=xadd)>>8]<<24|
  3797.           chunky->framebuffer[(xpo+=xadd)>>8]<<16|
  3798.           chunky->framebuffer[(xpo+=xadd)>>8]<<8|
  3799.           chunky->framebuffer[(xpo+=xadd)>>8],
  3800.  
  3801.         *d++=chunky->framebuffer[(xpo+=xadd)>>8]<<24|
  3802.           chunky->framebuffer[(xpo+=xadd)>>8]<<16|
  3803.           chunky->framebuffer[(xpo+=xadd)>>8]<<8|
  3804.           chunky->framebuffer[(xpo+=xadd)>>8],
  3805.  
  3806.         xpo+=xadd; /* !! */
  3807.   } else {
  3808.  
  3809.     for (ypo=0, d=(ULONG *)display->framebuffer, y=0; y<display->height;
  3810.       d=(ULONG *)((ULONG)d+modulo), ypo+=yadd, y++)
  3811.       for (t=(ULONG *)(chunky->framebuffer+chunky->width_align*(ypo>>8)),
  3812.            x=0; x<display->width_align; x+=16)
  3813.         *d++=*t++, *d++=*t++, *d++=*t++, *d++=*t++; /* !! */
  3814.   }
  3815.  
  3816. #if AW_SCALEDEBUG
  3817.   display->height++;
  3818. #endif
  3819. }
  3820.  
  3821. #endif
  3822.  
  3823.  
  3824. /* LUT8 scale + remap chunky buffer, 24.8 precision
  3825. */
  3826.  
  3827. void awremapscalechunky8(struct awdisplay *display,
  3828.   struct awchunky *chunky) {
  3829.  
  3830. #if AW_USEREMAPSCALE68K
  3831.  
  3832. #if AW_SCALEDEBUG
  3833.   display->height--;
  3834. #endif
  3835.  
  3836.   awddremapscalech68k8(
  3837.     chunky->framebuffer,
  3838.     display->framebuffer,
  3839.     display->remap,
  3840.     chunky->width,
  3841.     chunky->height,
  3842.     display->width,
  3843.     display->height,
  3844.     display->width_align);
  3845.  
  3846. #if AW_SCALEDEBUG
  3847.   display->height++;
  3848. #endif
  3849. }
  3850.  
  3851. #else
  3852.  
  3853.   ULONG x,y,xpo,ypo,xadd,yadd,*d;
  3854.   UBYTE *s;
  3855.  
  3856. #if AW_SCALEDEBUG
  3857.   display->height--;
  3858. #endif
  3859.  
  3860.   xadd=(chunky->width<<8)/display->width;
  3861.   yadd=(chunky->height<<8)/display->height;
  3862.  
  3863.   if (xadd!=256) {
  3864.  
  3865.     for (ypo=0, d=(ULONG *)display->framebuffer, y=0; y<display->height;
  3866.       ypo+=yadd, y++)
  3867.       for (xpo=chunky->width_align*(ypo&0xffffff00),x=0;
  3868.         x<display->width_align; x+=16)
  3869.  
  3870.         *d++=display->remap[chunky->framebuffer[xpo>>8]]<<24|
  3871.           display->remap[chunky->framebuffer[(xpo+=xadd)>>8]]<<16|
  3872.           display->remap[chunky->framebuffer[(xpo+=xadd)>>8]]<<8|
  3873.           display->remap[chunky->framebuffer[(xpo+=xadd)>>8]],
  3874.  
  3875.         *d++=display->remap[chunky->framebuffer[(xpo+=xadd)>>8]]<<24|
  3876.           display->remap[chunky->framebuffer[(xpo+=xadd)>>8]]<<16|
  3877.           display->remap[chunky->framebuffer[(xpo+=xadd)>>8]]<<8|
  3878.           display->remap[chunky->framebuffer[(xpo+=xadd)>>8]],
  3879.  
  3880.         *d++=display->remap[chunky->framebuffer[(xpo+=xadd)>>8]]<<24|
  3881.           display->remap[chunky->framebuffer[(xpo+=xadd)>>8]]<<16|
  3882.           display->remap[chunky->framebuffer[(xpo+=xadd)>>8]]<<8|
  3883.           display->remap[chunky->framebuffer[(xpo+=xadd)>>8]],
  3884.  
  3885.         *d++=display->remap[chunky->framebuffer[(xpo+=xadd)>>8]]<<24|
  3886.           display->remap[chunky->framebuffer[(xpo+=xadd)>>8]]<<16|
  3887.           display->remap[chunky->framebuffer[(xpo+=xadd)>>8]]<<8|
  3888.           display->remap[chunky->framebuffer[(xpo+=xadd)>>8]],
  3889.  
  3890.         xpo+=xadd; /* !! */
  3891.  
  3892.   } else {
  3893.     for (ypo=0, d=(ULONG *)display->framebuffer, y=0; y<display->height;
  3894.       ypo+=yadd, y++)
  3895.       for (x=0, s=chunky->framebuffer+chunky->width_align*(ypo>>8);
  3896.         x<display->width_align; x+=16)
  3897.  
  3898.         *d++=display->remap[s[0]]<<24 | display->remap[s[1]]<<16 |
  3899.           display->remap[s[2]]<<8 | display->remap[s[3]],
  3900.  
  3901.         *d++=display->remap[s[4]]<<24 | display->remap[s[5]]<<16 |
  3902.           display->remap[s[6]]<<8 | display->remap[s[7]],
  3903.  
  3904.         *d++=display->remap[s[8]]<<24 | display->remap[s[9]]<<16 |
  3905.           display->remap[s[10]]<<8 | display->remap[s[11]],
  3906.  
  3907.         *d++=display->remap[s[12]]<<24 | display->remap[s[13]]<<16 |
  3908.           display->remap[s[14]]<<8 | display->remap[s[15]],
  3909.  
  3910.         s+=16; /* !! */
  3911.   }
  3912.  
  3913. #if AW_SCALEDEBUG
  3914.   display->height++;
  3915. #endif
  3916. }
  3917.  
  3918. #endif
  3919.  
  3920.  
  3921. /* RGB16 -> LUT8 scale and remap routines */
  3922.  
  3923.  
  3924. /* RGB565 scale chunky buffer, 24.8 precision
  3925.    output LUT8
  3926. */
  3927.  
  3928. void awscalechunky16(struct awdisplay *display,
  3929.   struct awchunky *chunky) {
  3930.  
  3931. #if AW_USEREMAPSCALE68K16
  3932.  
  3933. #if AW_SCALEDEBUG
  3934.   display->height--;
  3935. #endif
  3936.  
  3937.   awddscalech68k16(
  3938.     chunky->framebuffer,
  3939.     display->framebuffer,
  3940.     chunky->width,
  3941.     chunky->height,
  3942.     display->width,
  3943.     display->height,
  3944.     display->width_align,
  3945.     display->pixperrow);
  3946.  
  3947. #if AW_SCALEDEBUG
  3948.   display->height++;
  3949. #endif
  3950. }
  3951.  
  3952. #else
  3953.  
  3954.   ULONG x,y,xpo,ypo,xadd,yadd,modulo,*d;
  3955.   UWORD *framebuffer=(UWORD *)chunky->framebuffer;
  3956.  
  3957. #if AW_SCALEDEBUG
  3958.   display->height--;
  3959. #endif
  3960.  
  3961.   modulo=display->pixperrow-display->width_align;
  3962.  
  3963.   xadd=(chunky->width<<8)/display->width;
  3964.   yadd=(chunky->height<<8)/display->height;
  3965.  
  3966.   if (xadd!=256) {
  3967.  
  3968.     for (ypo=0, d=(ULONG *)display->framebuffer, y=0; y<display->height;
  3969.       d=(ULONG *)((ULONG)d+modulo), ypo+=yadd, y++)
  3970.       for (xpo=chunky->width_align*(ypo&0xffffff00), x=0;
  3971.         x<display->width_align; x+=16)
  3972.  
  3973.         /* can't use (xpo+=xadd) because awrgb16to332 is a macro */
  3974.  
  3975.         *d++=awrgb16to332(framebuffer[(xpo+xadd*0)>>8])<<24|
  3976.           awrgb16to332(framebuffer[(xpo+xadd*1)>>8])<<16|
  3977.           awrgb16to332(framebuffer[(xpo+xadd*2)>>8])<<8|
  3978.           awrgb16to332(framebuffer[(xpo+xadd*3)>>8]),
  3979.  
  3980.         *d++=awrgb16to332(framebuffer[(xpo+xadd*4)>>8])<<24|
  3981.           awrgb16to332(framebuffer[(xpo+xadd*5)>>8])<<16|
  3982.           awrgb16to332(framebuffer[(xpo+xadd*6)>>8])<<8|
  3983.           awrgb16to332(framebuffer[(xpo+xadd*7)>>8]),
  3984.  
  3985.         *d++=awrgb16to332(framebuffer[(xpo+xadd*8)>>8])<<24|
  3986.           awrgb16to332(framebuffer[(xpo+xadd*9)>>8])<<16|
  3987.           awrgb16to332(framebuffer[(xpo+xadd*10)>>8])<<8|
  3988.           awrgb16to332(framebuffer[(xpo+xadd*11)>>8]),
  3989.  
  3990.         *d++=awrgb16to332(framebuffer[(xpo+xadd*12)>>8])<<24|
  3991.           awrgb16to332(framebuffer[(xpo+xadd*13)>>8])<<16|
  3992.           awrgb16to332(framebuffer[(xpo+xadd*14)>>8])<<8|
  3993.           awrgb16to332(framebuffer[(xpo+xadd*15)>>8]),
  3994.  
  3995.           xpo+=xadd*16; /* !! */
  3996.   } else {
  3997.  
  3998.     for (ypo=0, d=(ULONG *)display->framebuffer, y=0; y<display->height;
  3999.       d=(ULONG *)((ULONG)d+modulo), ypo+=yadd, y++)
  4000.       for (framebuffer=(UWORD *)(chunky->framebuffer+
  4001.         (chunky->width_align<<1)*(ypo>>8)),
  4002.         x=0; x<display->width_align; x+=16)
  4003.  
  4004.         *d++=awrgb16to332(framebuffer[0])<<24|
  4005.           awrgb16to332(framebuffer[1])<<16|
  4006.           awrgb16to332(framebuffer[2])<<8|
  4007.           awrgb16to332(framebuffer[3]),
  4008.  
  4009.         *d++=awrgb16to332(framebuffer[4])<<24|
  4010.           awrgb16to332(framebuffer[5])<<16|
  4011.           awrgb16to332(framebuffer[6])<<8|
  4012.           awrgb16to332(framebuffer[7]),
  4013.  
  4014.         *d++=awrgb16to332(framebuffer[8])<<24|
  4015.           awrgb16to332(framebuffer[9])<<16|
  4016.           awrgb16to332(framebuffer[10])<<8|
  4017.           awrgb16to332(framebuffer[11]),
  4018.  
  4019.         *d++=awrgb16to332(framebuffer[12])<<24|
  4020.           awrgb16to332(framebuffer[13])<<16|
  4021.           awrgb16to332(framebuffer[14])<<8|
  4022.           awrgb16to332(framebuffer[15]),
  4023.  
  4024.         framebuffer+=16; /* !! */
  4025.   }
  4026.  
  4027. #if AW_SCALEDEBUG
  4028.   display->height++;
  4029. #endif
  4030. }
  4031.  
  4032. #endif
  4033.  
  4034.  
  4035. /* RGB565 scale + remap chunky buffer, 24.8 precision
  4036.    output LUT8
  4037. */
  4038.  
  4039. void awremapscalechunky16(struct awdisplay *display,
  4040.   struct awchunky *chunky) {
  4041.  
  4042. #if AW_USEREMAPSCALE68K16
  4043.  
  4044. #if AW_SCALEDEBUG
  4045.   display->height--;
  4046. #endif
  4047.  
  4048.   awddremapscalech68k16(
  4049.     chunky->framebuffer,
  4050.     display->framebuffer,
  4051.     display->remap,
  4052.     chunky->width,
  4053.     chunky->height,
  4054.     display->width,
  4055.     display->height,
  4056.     display->width_align);
  4057.  
  4058. #if AW_SCALEDEBUG
  4059.   display->height++;
  4060. #endif
  4061. }
  4062.  
  4063. #else
  4064.  
  4065.   ULONG x,y,xpo,ypo,xadd,yadd,*d;
  4066.   UWORD *s,*framebuffer=(UWORD *)chunky->framebuffer;
  4067.  
  4068. #if AW_SCALEDEBUG
  4069.   display->height--;
  4070. #endif
  4071.  
  4072.   xadd=(chunky->width<<8)/display->width;
  4073.   yadd=(chunky->height<<8)/display->height;
  4074.  
  4075.   if (xadd!=256) {
  4076.  
  4077.     for (ypo=0, d=(ULONG *)display->framebuffer, y=0; y<display->height;
  4078.       ypo+=yadd, y++)
  4079.       for (xpo=chunky->width_align*(ypo&0xffffff00),x=0;
  4080.         x<display->width_align; x+=16)
  4081.  
  4082.         *d++=display->remap332[framebuffer[xpo>>8]]<<24|
  4083.           display->remap332[framebuffer[(xpo+=xadd)>>8]]<<16|
  4084.           display->remap332[framebuffer[(xpo+=xadd)>>8]]<<8|
  4085.           display->remap332[framebuffer[(xpo+=xadd)>>8]],
  4086.  
  4087.         *d++=display->remap332[framebuffer[(xpo+=xadd)>>8]]<<24|
  4088.           display->remap332[framebuffer[(xpo+=xadd)>>8]]<<16|
  4089.           display->remap332[framebuffer[(xpo+=xadd)>>8]]<<8|
  4090.           display->remap332[framebuffer[(xpo+=xadd)>>8]],
  4091.  
  4092.         *d++=display->remap332[framebuffer[(xpo+=xadd)>>8]]<<24|
  4093.           display->remap332[framebuffer[(xpo+=xadd)>>8]]<<16|
  4094.           display->remap332[framebuffer[(xpo+=xadd)>>8]]<<8|
  4095.           display->remap332[framebuffer[(xpo+=xadd)>>8]],
  4096.  
  4097.         *d++=display->remap332[framebuffer[(xpo+=xadd)>>8]]<<24|
  4098.           display->remap332[framebuffer[(xpo+=xadd)>>8]]<<16|
  4099.           display->remap332[framebuffer[(xpo+=xadd)>>8]]<<8|
  4100.           display->remap332[framebuffer[(xpo+=xadd)>>8]],
  4101.  
  4102.         xpo+=xadd; /* !! */
  4103.  
  4104.   } else {
  4105.  
  4106.     for (ypo=0, d=(ULONG *)display->framebuffer, y=0; y<display->height;
  4107.       ypo+=yadd, y++)
  4108.       for (x=0, s=(UWORD *)(chunky->framebuffer+
  4109.         (chunky->width_align<<1)*(ypo>>8));
  4110.         x<display->width_align; x+=16)
  4111.  
  4112.         *d++=display->remap332[s[0]]<<24 | display->remap332[s[1]]<<16 |
  4113.           display->remap332[s[2]]<<8 | display->remap332[s[3]],
  4114.  
  4115.         *d++=display->remap332[s[4]]<<24 | display->remap332[s[5]]<<16 |
  4116.           display->remap332[s[6]]<<8 | display->remap332[s[7]],
  4117.  
  4118.         *d++=display->remap332[s[8]]<<24 | display->remap332[s[9]]<<16 |
  4119.           display->remap332[s[10]]<<8 | display->remap332[s[11]],
  4120.  
  4121.         *d++=display->remap332[s[12]]<<24 | display->remap332[s[13]]<<16 |
  4122.           display->remap332[s[14]]<<8 | display->remap332[s[15]],
  4123.  
  4124.         s+=16; /* !! */
  4125.   }
  4126.  
  4127. #if AW_SCALEDEBUG
  4128.   display->height++;
  4129. #endif
  4130.  
  4131. }
  4132.  
  4133. #endif
  4134.  
  4135. /* RGB565 scale chunky buffer, 24.8 precision
  4136.    output RGB565
  4137. */
  4138.  
  4139. void awscalechunky16_565(struct awdisplay *display,
  4140.   struct awchunky *chunky) {
  4141.  
  4142. #if AW_USEREMAPSCALE68K16
  4143.  
  4144. #if AW_SCALEDEBUG
  4145.   display->height--;
  4146. #endif
  4147.  
  4148.   awddscalech68k16_565(
  4149.     chunky->framebuffer,
  4150.     display->framebuffer,
  4151.     chunky->width,
  4152.     chunky->height,
  4153.     display->width,
  4154.     display->height,
  4155.     display->width_align,
  4156.     display->pixperrow);
  4157.  
  4158. #if AW_SCALEDEBUG
  4159.   display->height++;
  4160. #endif
  4161. }
  4162.  
  4163. #else
  4164.  
  4165.   ULONG x,y,xpo,ypo,xadd,yadd,*t,modulo,*d;
  4166.   UWORD *framebuffer=(UWORD *)chunky->framebuffer;
  4167.  
  4168. #if AW_SCALEDEBUG
  4169.   display->height--;
  4170. #endif
  4171.  
  4172.   modulo=(display->pixperrow-display->width_align)*2;
  4173.  
  4174.   xadd=(chunky->width<<8)/display->width;
  4175.   yadd=(chunky->height<<8)/display->height;
  4176.  
  4177.   if (xadd!=256) {
  4178.  
  4179.     for (ypo=0, d=(ULONG *)display->framebuffer, y=0; y<display->height;
  4180.       d=(ULONG *)((ULONG)d+modulo), ypo+=yadd, y++)
  4181.       for (xpo=chunky->width_align*(ypo&0xffffff00), x=0;
  4182.         x<display->width_align; x+=16)
  4183.  
  4184.         *d++=framebuffer[xpo>>8]<<16|
  4185.           framebuffer[(xpo+=xadd)>>8],
  4186.         *d++=framebuffer[(xpo+=xadd)>>8]<<16|
  4187.           framebuffer[(xpo+=xadd)>>8],
  4188.  
  4189.         *d++=framebuffer[(xpo+=xadd)>>8]<<16|
  4190.           framebuffer[(xpo+=xadd)>>8],
  4191.         *d++=framebuffer[(xpo+=xadd)>>8]<<16|
  4192.           framebuffer[(xpo+=xadd)>>8],
  4193.  
  4194.         *d++=framebuffer[(xpo+=xadd)>>8]<<16|
  4195.           framebuffer[(xpo+=xadd)>>8],
  4196.         *d++=framebuffer[(xpo+=xadd)>>8]<<16|
  4197.           framebuffer[(xpo+=xadd)>>8],
  4198.  
  4199.         *d++=framebuffer[(xpo+=xadd)>>8]<<16|
  4200.           framebuffer[(xpo+=xadd)>>8],
  4201.         *d++=framebuffer[(xpo+=xadd)>>8]<<16|
  4202.           framebuffer[(xpo+=xadd)>>8],
  4203.  
  4204.         xpo+=xadd; /* !! */
  4205.   } else {
  4206.  
  4207.     for (ypo=0, d=(ULONG *)display->framebuffer, y=0; y<display->height;
  4208.       d=(ULONG *)((ULONG)d+modulo), ypo+=yadd, y++)
  4209.       for (t=(ULONG *)(chunky->framebuffer+
  4210.         chunky->width_align*2*(ypo>>8)),
  4211.         x=0; x<display->width_align; x+=16)
  4212.  
  4213.         *d++=*t++, *d++=*t++, *d++=*t++, *d++=*t++,
  4214.         *d++=*t++, *d++=*t++, *d++=*t++, *d++=*t++; /* !! */
  4215.   }
  4216.  
  4217. #if AW_SCALEDEBUG
  4218.   display->height++;
  4219. #endif
  4220. }
  4221.  
  4222. #endif
  4223.  
  4224.  
  4225. /* RGB565 scale chunky buffer, 24.8 precision
  4226.    output ARGB
  4227. */
  4228.  
  4229. void awscalechunky16_argb(struct awdisplay *display,
  4230.   struct awchunky *chunky) {
  4231.  
  4232. #if AW_USEREMAPSCALE68K16
  4233.  
  4234. #if AW_SCALEDEBUG
  4235.   display->height--;
  4236. #endif
  4237.  
  4238.   awddscalech68k16_argb(
  4239.     chunky->framebuffer,
  4240.     display->framebuffer,
  4241.     chunky->width,
  4242.     chunky->height,
  4243.     display->width,
  4244.     display->height,
  4245.     display->width_align,
  4246.     display->pixperrow);
  4247.  
  4248. #if AW_SCALEDEBUG
  4249.   display->height++;
  4250. #endif
  4251. }
  4252.  
  4253. #else
  4254.  
  4255.   ULONG x,y,xpo,ypo,xadd,yadd,modulo,*d;
  4256.   UWORD *framebuffer=(UWORD *)chunky->framebuffer;
  4257.  
  4258. #if AW_SCALEDEBUG
  4259.   display->height--;
  4260. #endif
  4261.  
  4262.   modulo=(display->pixperrow-display->width_align)*2;
  4263.  
  4264.   xadd=(chunky->width<<8)/display->width;
  4265.   yadd=(chunky->height<<8)/display->height;
  4266.  
  4267.   if (xadd!=256) {
  4268.  
  4269.     for (ypo=0, d=(ULONG *)display->framebuffer, y=0; y<display->height;
  4270.       d=(ULONG *)((ULONG)d+modulo), ypo+=yadd, y++)
  4271.       for (xpo=chunky->width_align*(ypo&0xffffff00), x=0;
  4272.         x<display->width_align; x+=16)
  4273.  
  4274.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*0)>>8]),
  4275.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*1)>>8]),
  4276.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*2)>>8]),
  4277.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*3)>>8]),
  4278.  
  4279.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*4)>>8]),
  4280.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*5)>>8]),
  4281.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*6)>>8]),
  4282.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*7)>>8]),
  4283.  
  4284.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*8)>>8]),
  4285.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*9)>>8]),
  4286.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*10)>>8]),
  4287.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*11)>>8]),
  4288.  
  4289.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*12)>>8]),
  4290.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*13)>>8]),
  4291.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*14)>>8]),
  4292.         *d++=awrgb16to0888(framebuffer[(xpo+xadd*15)>>8]),
  4293.  
  4294.         xpo+=xadd*16; /* !! */
  4295.   } else {
  4296.  
  4297.     for (ypo=0, d=(ULONG *)display->framebuffer, y=0; y<display->height;
  4298.       d=(ULONG *)((ULONG)d+modulo), ypo+=yadd, y++)
  4299.       for (framebuffer=(UWORD *)(chunky->framebuffer+
  4300.         chunky->width_align*2*(ypo>>8)),
  4301.         x=0; x<display->width_align; x+=16)
  4302.  
  4303.         *d++=awrgb16to0888(framebuffer[0]),
  4304.         *d++=awrgb16to0888(framebuffer[1]),
  4305.         *d++=awrgb16to0888(framebuffer[2]),
  4306.         *d++=awrgb16to0888(framebuffer[3]),
  4307.  
  4308.         *d++=awrgb16to0888(framebuffer[4]),
  4309.         *d++=awrgb16to0888(framebuffer[5]),
  4310.         *d++=awrgb16to0888(framebuffer[6]),
  4311.         *d++=awrgb16to0888(framebuffer[7]),
  4312.  
  4313.         *d++=awrgb16to0888(framebuffer[8]),
  4314.         *d++=awrgb16to0888(framebuffer[9]),
  4315.         *d++=awrgb16to0888(framebuffer[10]),
  4316.         *d++=awrgb16to0888(framebuffer[11]),
  4317.  
  4318.         *d++=awrgb16to0888(framebuffer[12]),
  4319.         *d++=awrgb16to0888(framebuffer[13]),
  4320.         *d++=awrgb16to0888(framebuffer[14]),
  4321.         *d++=awrgb16to0888(framebuffer[15]),
  4322.  
  4323.         framebuffer+=16; /* !! */
  4324.   }
  4325.  
  4326. #if AW_SCALEDEBUG
  4327.   display->height++;
  4328. #endif
  4329. }
  4330.  
  4331. #endif
  4332.  
  4333.  
  4334.  
  4335. void awiwaitsafetowrite(struct awdisplay *display) {
  4336. #if defined(AW_PPC)
  4337.   struct Caos kaaos;
  4338.  
  4339.   /* -*- odump by Harry "Piru" Sintonen */
  4340.   static const ULONG awsafewaitinner[]={
  4341.     0x48e72020,0x24002448,0x204a4eae,0xfe8c4a80,
  4342.     0x66082002,0x4eaefec2,0x60ee4cdf,0x04044e75,
  4343.     0};
  4344.   /* -*- */
  4345. #else
  4346.   struct ExecBase *SysBase=display->SysBase;
  4347. #endif
  4348.  
  4349.   if (display->dbuffer) {
  4350.     if (!display->safetowrite) {
  4351. #if defined(AW_PPC)
  4352.       kaaos.d0=1L<<(display->sbports[AW_WRITEPORT]->mp_SigBit);
  4353.       kaaos.a0=(ULONG)display->sbports[AW_WRITEPORT];
  4354.       kaaos.a6=(ULONG)display->SysBase;
  4355.       kaaos.caos_Un.Function=(APTR)awsafewaitinner;
  4356.       kaaos.M68kCacheMode=IF_CACHEFLUSHNO;
  4357.       kaaos.PPCCacheMode=IF_CACHEFLUSHNO;
  4358.       PPCCallM68k(&kaaos);
  4359. #else
  4360.       while (!GetMsg(display->sbports[AW_WRITEPORT]))
  4361.         Wait(1L<<(display->sbports[AW_WRITEPORT]->mp_SigBit));
  4362. #endif
  4363.       display->safetowrite=1;
  4364.     }
  4365.   }
  4366. }
  4367.  
  4368.  
  4369. void awidirectdraw8(struct awdisplay *display,
  4370.   struct awchunky *chunky) {
  4371.  
  4372.   struct Library *CyberGfxBase=display->CyberGfxBase;
  4373.   APTR handle;
  4374.   ULONG width,height,pixfmt,bpp;
  4375.   /* save original variables */
  4376.   ULONG orig_pixperrow=display->pixperrow;
  4377.   UBYTE *orig_framebuffer=display->framebuffer;
  4378.  
  4379.   struct TagItem lbm_tags[7];
  4380.  
  4381.   lbm_tags[0].ti_Tag=LBMI_WIDTH;      lbm_tags[0].ti_Data=(ULONG)&width;
  4382.   lbm_tags[1].ti_Tag=LBMI_HEIGHT;     lbm_tags[1].ti_Data=(ULONG)&height;
  4383.   lbm_tags[2].ti_Tag=LBMI_PIXFMT,     lbm_tags[2].ti_Data=(ULONG)&pixfmt;
  4384.   lbm_tags[3].ti_Tag=LBMI_BYTESPERPIX;lbm_tags[3].ti_Data=(ULONG)&bpp;
  4385.   lbm_tags[4].ti_Tag=LBMI_BYTESPERROW;lbm_tags[4].ti_Data=(ULONG)&display->pixperrow;
  4386.   lbm_tags[5].ti_Tag=LBMI_BASEADDRESS;lbm_tags[5].ti_Data=(ULONG)&display->framebuffer;
  4387.   lbm_tags[6].ti_Tag=TAG_DONE;
  4388.  
  4389.   handle=LockBitMapTagList(
  4390.     display->renderrp.BitMap,
  4391.     lbm_tags);
  4392.  
  4393.   if (handle) {
  4394.     if ( (pixfmt==PIXFMT_LUT8) && (bpp==1) &&
  4395.          (width==display->scrwidth) &&
  4396.          (height==display->height) ) {
  4397.  
  4398.       /* scale chunky directly to gfxcard framebuffer */
  4399.       awscalechunky8(display,chunky);
  4400.     }
  4401.  
  4402.     UnLockBitMap(handle);
  4403.   }
  4404.   /* restore original variables */
  4405.   display->framebuffer=orig_framebuffer;
  4406.   display->pixperrow=orig_pixperrow;
  4407. }
  4408.  
  4409.  
  4410. void awidirectdraw16(struct awdisplay *display,
  4411.   struct awchunky *chunky) {
  4412.  
  4413.   struct Library *CyberGfxBase=display->CyberGfxBase;
  4414.   APTR handle;
  4415.   ULONG width,height,pixfmt,bpp;
  4416.   /* save original variables */
  4417.   ULONG orig_pixperrow=display->pixperrow;
  4418.   UBYTE *orig_framebuffer=display->framebuffer;
  4419.  
  4420.   struct TagItem lbm_tags[7];
  4421.  
  4422.   lbm_tags[0].ti_Tag=LBMI_WIDTH;      lbm_tags[0].ti_Data=(ULONG)&width;
  4423.   lbm_tags[1].ti_Tag=LBMI_HEIGHT;     lbm_tags[1].ti_Data=(ULONG)&height;
  4424.   lbm_tags[2].ti_Tag=LBMI_PIXFMT,     lbm_tags[2].ti_Data=(ULONG)&pixfmt;
  4425.   lbm_tags[3].ti_Tag=LBMI_BYTESPERPIX;lbm_tags[3].ti_Data=(ULONG)&bpp;
  4426.   lbm_tags[4].ti_Tag=LBMI_BYTESPERROW;lbm_tags[4].ti_Data=(ULONG)&display->pixperrow;
  4427.   lbm_tags[5].ti_Tag=LBMI_BASEADDRESS;lbm_tags[5].ti_Data=(ULONG)&display->framebuffer;
  4428.   lbm_tags[6].ti_Tag=TAG_DONE;
  4429.  
  4430.   handle=LockBitMapTagList(
  4431.     display->renderrp.BitMap,
  4432.     lbm_tags);
  4433.  
  4434.   if (handle) {
  4435.     if ( (pixfmt==PIXFMT_RGB16) && (bpp==2) &&
  4436.          (width==display->scrwidth) &&
  4437.          (height==display->height) ) {
  4438.  
  4439.       display->pixperrow/=2;
  4440.  
  4441.       /* scale chunky directly to gfxcard framebuffer */
  4442.       awscalechunky16_565(display,chunky);
  4443.     }
  4444.  
  4445.     UnLockBitMap(handle);
  4446.   }
  4447.   /* restore original variables */
  4448.   display->framebuffer=orig_framebuffer;
  4449.   display->pixperrow=orig_pixperrow;
  4450. }
  4451.  
  4452.  
  4453. #if AW_CGXVIDEOSUPPORT
  4454.  
  4455. /* render rgb565 chunky to cgxvideo.library vlayer rgb565 pc */
  4456.  
  4457. void awwritevlayer(struct awdisplay *display,
  4458.   struct awchunky *chunky) {
  4459.  
  4460.   struct Library *CGXVideoBase=display->CGXVideoBase;
  4461.   UWORD *d,*s;
  4462.   ULONG x,y,*e,*t;
  4463.  
  4464.   if (LockVLayer(display->vlhandle)) {
  4465.  
  4466.     d=(UWORD *)GetVLayerAttr(display->vlhandle,VOA_BaseAddress);
  4467.  
  4468.     if (display->vlwidth & 15) {
  4469.  
  4470.       /* ab -> ba */
  4471.  
  4472.       for (y=0; y<display->vlheight; y++)
  4473.         for (x=0, s=(UWORD *)chunky->framebuffer+chunky->width_align*y*2;
  4474.           x<display->vlwidth; x++)
  4475.  
  4476.           *d++=(s[0]<<8)|(s[0]>>8), s++;
  4477.  
  4478.     } else {
  4479.  
  4480.       /* abcd -> badc */
  4481.  
  4482.       t=(ULONG *)d;
  4483.  
  4484.       for (y=0; y<display->vlheight; y++)
  4485.         for (x=0, e=(ULONG *)chunky->framebuffer+chunky->width_align*y*2;
  4486.           x<display->vlwidth; x+=16)
  4487.  
  4488.           *t++=(e[0]&0xff00ff00)>>8 | (e[0]&0x00ff00ff)<<8,
  4489.           *t++=(e[1]&0xff00ff00)>>8 | (e[1]&0x00ff00ff)<<8,
  4490.           *t++=(e[2]&0xff00ff00)>>8 | (e[2]&0x00ff00ff)<<8,
  4491.           *t++=(e[3]&0xff00ff00)>>8 | (e[3]&0x00ff00ff)<<8, e+=4; /* !! */
  4492.     }
  4493.  
  4494.     UnLockVLayer(display->vlhandle);
  4495.   }
  4496. }
  4497. #endif
  4498.  
  4499. void awirenderchunky(struct awdisplay *display,
  4500.   struct awchunky *chunky) {
  4501.  
  4502.   struct GfxBase *GfxBase=display->GfxBase;
  4503.   struct IntuitionBase *IntuitionBase=display->IntuitionBase;
  4504.   struct Library *CyberGfxBase;
  4505. #if defined(__GNUC__) && !defined(AW_PPC)
  4506.   struct writepixelarrayargs wpa;
  4507.   struct writelutpixelarrayargs wluta;
  4508. #endif
  4509.   ULONG orig_pixperrow,orig_width;
  4510.  
  4511. #if defined(AW_PPC)
  4512.   struct Caos kaaos;
  4513.  
  4514.   /* -*- odump by Harry "Piru" Sintonen */
  4515.   static const ULONG awsafewaitinner[]={
  4516.     0x48e72020,0x24002448,0x204a4eae,0xfe8c4a80,
  4517.     0x66082002,0x4eaefec2,0x60ee4cdf,0x04044e75,
  4518.     0};
  4519.   /* -*- */
  4520. #else
  4521.   struct ExecBase *SysBase=display->SysBase;
  4522. #endif
  4523.  
  4524. #if AW_SCALEDEBUG
  4525.   display->framebuffer[display->width_align*(display->height-1)]=127;
  4526.   display->framebuffer[display->width_align*(display->height-1)+2]=127;
  4527.   display->framebuffer[display->width_align*display->height-3]=127;
  4528.   display->framebuffer[display->width_align*display->height-1]=127;
  4529. #endif
  4530.  
  4531.   if (display->windowmode) {
  4532.  
  4533. #if AW_CGXVIDEOSUPPORT
  4534.     if (display->vlhandle) {
  4535.  
  4536.       /* render to vlayer,
  4537.          basically this is just copymem with every byte swapped.
  4538.          we know that chunky depth is 16, too. */
  4539.  
  4540.       awwritevlayer(display,chunky);
  4541.  
  4542.     } else {
  4543. #endif
  4544.  
  4545.     if (display->cgfx) {
  4546.       CyberGfxBase=display->CyberGfxBase;
  4547.  
  4548.       if (display->truecolor) {
  4549.  
  4550.         if (display->useargb16 && (display->srcdepth==16) ) {
  4551.           /* we have hi/true colour CGFX/P96 screen for output,
  4552.              USEARGB16 flag set and depth 16 source
  4553.              so scale to ARGB and then WPA */
  4554.  
  4555.           awscalechunky16_argb(display,chunky);
  4556.  
  4557. #if !defined(__GNUC__) || defined(AW_PPC)
  4558.           WritePixelArray(
  4559.             display->framebuffer,0,0,
  4560.             display->width_align*4,
  4561.             display->window->RPort,
  4562.             display->window->BorderLeft,
  4563.             display->window->BorderTop,
  4564.             awtoinnerw(display,display->window->Width),
  4565.             awtoinnerh(display,display->window->Height),
  4566.             RECTFMT_ARGB);
  4567. #else
  4568.           wpa.srcrect=display->framebuffer;
  4569.           wpa.srcx=0; wpa.srcy=0;
  4570.           wpa.srcmod=display->width_align*4;
  4571.           wpa.rastport=display->window->RPort;
  4572.           wpa.dstx=display->window->BorderLeft;
  4573.           wpa.dsty=display->window->BorderTop;
  4574.           wpa.sizex=awtoinnerw(display,display->window->Width);
  4575.           wpa.sizey=awtoinnerh(display,display->window->Height);
  4576.           wpa.srcf=RECTFMT_ARGB;
  4577.           wpa.base=CyberGfxBase;
  4578.           writepixelarray(&wpa);
  4579. #endif
  4580.  
  4581.         } else {
  4582.  
  4583.           if (display->wlutpa) {
  4584.             /* we have >8 depth cybergraphx so first scale chunky */
  4585.             if (display->srcdepth==16)
  4586.               awscalechunky16(display,chunky);
  4587.             else awscalechunky8(display,chunky);
  4588.  
  4589.             /* then WriteLUTPixelArray */
  4590.  
  4591. #if !defined(__GNUC__) || defined(AW_PPC)
  4592.             WriteLUTPixelArray(
  4593.               display->framebuffer,
  4594.               0,0,
  4595.               display->width_align,
  4596.               display->window->RPort,
  4597.               (ULONG *)((display->srcdepth==16)?display->pal332:
  4598.                 display->palette),
  4599.               display->window->BorderLeft,
  4600.               display->window->BorderTop,
  4601.               awtoinnerw(display,display->window->Width),
  4602.               awtoinnerh(display,display->window->Height),
  4603.               CTABFMT_XRGB8);
  4604. #else
  4605.             wluta.srcrect=display->framebuffer;
  4606.             wluta.srcx=0; wluta.srcy=0;
  4607.             wluta.srcmod=display->width_align;
  4608.             wluta.rastport=display->window->RPort;
  4609.             wluta.ctable=(display->srcdepth==16)?display->pal332:display->palette;
  4610.             wluta.dstx=display->window->BorderLeft;
  4611.             wluta.dsty=display->window->BorderTop;
  4612.             wluta.sizex=awtoinnerw(display,display->window->Width);
  4613.             wluta.sizey=awtoinnerh(display,display->window->Height);
  4614.             wluta.ctabf=CTABFMT_XRGB8;
  4615.             wluta.base=CyberGfxBase;
  4616.             writelutpixelarray(&wluta);
  4617. #endif
  4618.  
  4619.           } else {
  4620.  
  4621.             /* we have truecolor cybergraphx and no WLUTPA
  4622.                so remap & scale self and WPA */
  4623.  
  4624.             /* remap & scale chunky to display */
  4625.             if (display->srcdepth==16)
  4626.               awremapscalechunky16(display,chunky);
  4627.             else awremapscalechunky8(display,chunky);
  4628.  
  4629. #if !defined(__GNUC__) || defined(AW_PPC)
  4630.             WritePixelArray(
  4631.               display->framebuffer,0,0,
  4632.               display->width_align,
  4633.               display->window->RPort,
  4634.               display->window->BorderLeft,
  4635.               display->window->BorderTop,
  4636.               awtoinnerw(display,display->window->Width),
  4637.               awtoinnerh(display,display->window->Height),
  4638.               RECTFMT_LUT8);
  4639. #else
  4640.             wpa.srcrect=display->framebuffer;
  4641.             wpa.srcx=0; wpa.srcy=0;
  4642.             wpa.srcmod=display->width_align;
  4643.             wpa.rastport=display->window->RPort;
  4644.             wpa.dstx=display->window->BorderLeft;
  4645.             wpa.dsty=display->window->BorderTop;
  4646.             wpa.sizex=awtoinnerw(display,display->window->Width);
  4647.             wpa.sizey=awtoinnerh(display,display->window->Height);
  4648.             wpa.srcf=RECTFMT_LUT8;
  4649.             wpa.base=CyberGfxBase;
  4650.             writepixelarray(&wpa);
  4651. #endif
  4652.           }
  4653.         }
  4654.  
  4655.       } else {
  4656.  
  4657.         /* we have <=8 depth cybergraphx so scale self and WPA */
  4658.  
  4659.         /* remap & scale chunky to display */
  4660.         if (display->srcdepth==16)
  4661.           awremapscalechunky16(display,chunky);
  4662.         else awremapscalechunky8(display,chunky);
  4663.  
  4664. #if !defined(__GNUC__) || defined(AW_PPC)
  4665.         WritePixelArray(
  4666.           display->framebuffer,0,0,
  4667.           display->width_align,
  4668.           display->window->RPort,
  4669.           display->window->BorderLeft,
  4670.           display->window->BorderTop,
  4671.           awtoinnerw(display,display->window->Width),
  4672.           awtoinnerh(display,display->window->Height),
  4673.           RECTFMT_LUT8);
  4674. #else
  4675.         wpa.srcrect=display->framebuffer;
  4676.         wpa.srcx=0; wpa.srcy=0;
  4677.         wpa.srcmod=display->width_align;
  4678.         wpa.rastport=display->window->RPort;
  4679.         wpa.dstx=display->window->BorderLeft;
  4680.         wpa.dsty=display->window->BorderTop;
  4681.         wpa.sizex=awtoinnerw(display,display->window->Width);
  4682.         wpa.sizey=awtoinnerh(display,display->window->Height);
  4683.         wpa.srcf=RECTFMT_LUT8;
  4684.         wpa.base=CyberGfxBase;
  4685.         writepixelarray(&wpa);
  4686. #endif
  4687.  
  4688.       }
  4689.     } else {
  4690.  
  4691.       if ( (display->native) &&
  4692.            ((display->fblit) || (display->slowwpa8)) ) {
  4693.  
  4694.         /* native system with fblit or slow WCP/WPA8 */
  4695.  
  4696.         /* remap & scale chunky to display */
  4697.         if (display->srcdepth==16)
  4698.           awremapscalechunky16(display,chunky);
  4699.         else awremapscalechunky8(display,chunky);
  4700.  
  4701.  
  4702.         /* do c2p */
  4703.         awdoc2p(display);
  4704.  
  4705.         /* and then blit resulting planes to rastport */
  4706.         BltBitMapRastPort(
  4707.           &display->c2pbitmap[0],0,0,
  4708.           display->window->RPort,
  4709.           display->window->BorderLeft,
  4710.           display->window->BorderTop,
  4711.           awtoinnerw(display,display->window->Width),
  4712.           awtoinnerh(display,display->window->Height),
  4713.           0xc0);
  4714.  
  4715.       } else {
  4716.  
  4717.         /* general system */
  4718.  
  4719.         /* remap & scale chunky to display */
  4720.         if (display->srcdepth==16)
  4721.           awremapscalechunky16(display,chunky);
  4722.         else awremapscalechunky8(display,chunky);
  4723.  
  4724.         /* bang it with WCP or WPA8 */
  4725.         if (display->v40) {
  4726.           WriteChunkyPixels(
  4727.             display->window->RPort,
  4728.             display->window->BorderLeft,
  4729.             display->window->BorderTop,
  4730.             display->window->BorderLeft+
  4731.               awtoinnerw(display,display->window->Width)-1,
  4732.             display->window->BorderTop+
  4733.               awtoinnerh(display,display->window->Height)-1,
  4734.             display->framebuffer,
  4735.             display->width_align);
  4736.         } else {
  4737.           WritePixelArray8(
  4738.             display->window->RPort,
  4739.             display->window->BorderLeft,
  4740.             display->window->BorderTop,
  4741.             display->window->BorderLeft+
  4742.               awtoinnerw(display,display->window->Width)-1,
  4743.             display->window->BorderTop+
  4744.               awtoinnerh(display,display->window->Height)-1,
  4745.             display->framebuffer,
  4746.             &display->temprp);
  4747.         }
  4748.       }
  4749.     }
  4750.  
  4751. #if AW_CGXVIDEOSUPPORT
  4752.     }
  4753. #endif
  4754.  
  4755.   } else {
  4756.  
  4757.     /* screen mode */
  4758.  
  4759.     if (display->dbuffer) {
  4760.       /* set renderrp BitMap according to curbuffer */
  4761.       display->renderrp.BitMap=
  4762.         display->sbuf[display->curbuffer]->sb_BitMap;
  4763.     } else {
  4764.       /* no dbuffer, set to standard bitmap */
  4765.       display->renderrp.BitMap=
  4766.         display->screen->RastPort.BitMap;
  4767.     }
  4768.  
  4769.     if (display->cgfx) {
  4770.       CyberGfxBase=display->CyberGfxBase;
  4771.  
  4772.       if ( ((display->directdraw) && (display->islinearmem)) &&
  4773.            ((display->srcdepth==8) ||
  4774.             ((display->srcdepth==16) && (display->isrgb16))) ) {
  4775.  
  4776.         /* DirectDraw: scalechunky directly to CGFX bitmap */
  4777.  
  4778.         /* wait until it is safe to render */
  4779.         awiwaitsafetowrite(display);
  4780.  
  4781.         if (display->srcdepth==16)
  4782.           awidirectdraw16(display,chunky);
  4783.         else awidirectdraw8(display,chunky);
  4784.  
  4785.       } else {
  4786.  
  4787.         if (display->truecolor && display->useargb16 &&
  4788.             (display->srcdepth==16) ) {
  4789.           /* we have hi/true colour CGFX/P96 screen for output,
  4790.              USEARGB16 flag set and depth 16 source
  4791.              so scale to ARGB and then WPA */
  4792.  
  4793.           awscalechunky16_argb(display,chunky);
  4794.  
  4795. #if !defined(__GNUC__) || defined(AW_PPC)
  4796.           WritePixelArray(
  4797.             display->framebuffer,0,0,
  4798.             display->width_align*4,
  4799.             &display->renderrp,
  4800.             0,0,
  4801.             display->width,
  4802.             display->height,
  4803.             RECTFMT_ARGB);
  4804. #else
  4805.           wpa.srcrect=display->framebuffer;
  4806.           wpa.srcx=0; wpa.srcy=0;
  4807.           wpa.srcmod=display->width_align*4;
  4808.           wpa.rastport=&display->renderrp;
  4809.           wpa.dstx=0; wpa.dsty=0;
  4810.           wpa.sizex=display->width;
  4811.           wpa.sizey=display->height;
  4812.           wpa.srcf=RECTFMT_ARGB;
  4813.           wpa.base=CyberGfxBase;
  4814.           writepixelarray(&wpa);
  4815. #endif
  4816.  
  4817.         } else {
  4818.         /* we have cybergraphx so scale self and WPA */
  4819.  
  4820.         /* scale chunky to display */
  4821.         if (display->srcdepth==16)
  4822.           awscalechunky16(display,chunky);
  4823.         else awscalechunky8(display,chunky);
  4824.  
  4825. #if !defined(__GNUC__) || defined(AW_PPC)
  4826.         /* wait until it is safe to render */
  4827.         awiwaitsafetowrite(display);
  4828.  
  4829.         WritePixelArray(
  4830.           display->framebuffer,
  4831.           0,0,
  4832.           display->width_align,
  4833.           &display->renderrp,
  4834.           0,0,
  4835.           display->width,
  4836.           display->height,
  4837.           RECTFMT_LUT8);
  4838. #else
  4839.         wpa.srcrect=display->framebuffer;
  4840.         wpa.srcx=0; wpa.srcy=0;
  4841.         wpa.srcmod=display->width_align;
  4842.         wpa.rastport=&display->renderrp;
  4843.         wpa.dstx=0; wpa.dsty=0;
  4844.         wpa.sizex=display->width;
  4845.         wpa.sizey=display->height;
  4846.         wpa.srcf=RECTFMT_LUT8;
  4847.         wpa.base=CyberGfxBase;
  4848.         /* wait until it is safe to render */
  4849.         awiwaitsafetowrite(display);
  4850.         writepixelarray(&wpa);
  4851. #endif
  4852.  
  4853.       }
  4854.       }
  4855.     } else {
  4856.       if (display->native) {
  4857.  
  4858.         /* native system */
  4859.  
  4860.         /* force to render whole width because c2p converts
  4861.            whole buffer anyways (and has no modulo, ok this
  4862.            could be "fixed" but who cares.. really;) */
  4863.  
  4864.         orig_width=display->width;
  4865.         orig_pixperrow=display->pixperrow;
  4866.  
  4867.         display->width=display->width_align;
  4868.         display->pixperrow=display->width;
  4869.  
  4870.         /* scale chunky to display */
  4871.         if (display->srcdepth==16) {
  4872.           if (display->isham6) {
  4873.  
  4874.             display->width/=2;
  4875.             display->width_align/=2;
  4876.             display->pixperrow/=2;
  4877.             awscalechunky16_565(display,chunky);
  4878.             display->pixperrow*=2;
  4879.             display->width_align*=2;
  4880.             display->width*=2;
  4881.  
  4882.           } else awscalechunky16(display,chunky);
  4883.         } else awscalechunky8(display,chunky);
  4884.  
  4885.         display->pixperrow=orig_pixperrow;
  4886.         display->width=orig_width;
  4887.  
  4888.         /* wait until it is safe to render */
  4889.         awiwaitsafetowrite(display);
  4890.  
  4891.         /* do c2p */
  4892.         if ( (display->srcdepth==16) && (display->isham6) ) {
  4893.           awdoc2pham6(display);
  4894.         } else awdoc2p(display);
  4895.  
  4896.       } else {
  4897.  
  4898.         /* general system */
  4899.  
  4900.         /* scale chunky to display */
  4901.         if (display->srcdepth==16)
  4902.           awscalechunky16(display,chunky);
  4903.         else awscalechunky8(display,chunky);
  4904.  
  4905.         /* wait until it is safe to render */
  4906.         awiwaitsafetowrite(display);
  4907.  
  4908.         /* bang it with WCP or WPA8 */
  4909.         if (display->v40) {
  4910.           WriteChunkyPixels(
  4911.             &display->renderrp,
  4912.             0,0,
  4913.             display->width-1,
  4914.             display->height-1,
  4915.             display->framebuffer,
  4916.             display->width_align);
  4917.         } else {
  4918.           WritePixelArray8(
  4919.             &display->renderrp,
  4920.             0,0,
  4921.             display->width-1,
  4922.             display->height-1,
  4923.             display->framebuffer,
  4924.             &display->temprp);
  4925.         }
  4926.       }
  4927.     }
  4928.  
  4929.     if (display->dbuffer) {
  4930.       if (display->waitswap) {
  4931.         /* wait until it is safe to swap */
  4932.         if (!display->safetochange) {
  4933.  
  4934. #if defined(AW_PPC)
  4935.           kaaos.d0=1L<<(display->sbports[AW_DISPPORT]->mp_SigBit);
  4936.           kaaos.a0=(ULONG)display->sbports[AW_DISPPORT];
  4937.           kaaos.a6=(ULONG)display->SysBase;
  4938.           kaaos.caos_Un.Function=(APTR)awsafewaitinner;
  4939.           kaaos.M68kCacheMode=IF_CACHEFLUSHNO;
  4940.           kaaos.PPCCacheMode=IF_CACHEFLUSHNO;
  4941.           PPCCallM68k(&kaaos);
  4942. #else
  4943.           while (!GetMsg(display->sbports[AW_DISPPORT]))
  4944.             Wait(1L<<(display->sbports[AW_DISPPORT]->mp_SigBit));
  4945. #endif
  4946.           display->safetochange=1;
  4947.  
  4948.         }
  4949.       }
  4950.       /*if (display->native) WaitBlit();*/
  4951.       if (ChangeScreenBuffer(display->screen,
  4952.         display->sbuf[display->curbuffer])) {
  4953.  
  4954.         display->safetochange=0;
  4955.         display->safetowrite=0;
  4956.         display->curbuffer ^= 1;  /* toggle buffer */
  4957.       }
  4958.     }
  4959.   }
  4960. }
  4961.  
  4962. void awrenderchunky(struct awdisplay *display,
  4963.   struct awchunky *chunky) {
  4964.  
  4965.   ULONG ret=1,odepth=display->srcdepth,openscr=0;
  4966.  
  4967. #if AW_CGXVIDEOSUPPORT
  4968.   struct Library *CGXVideoBase;
  4969.   struct TagItem cvlh_tags[4];
  4970. #endif
  4971.  
  4972.   if (!display->stoprender) {
  4973.     display->rendering=1;
  4974.  
  4975.     /* this handles initial open */
  4976.     if (display->window==NULL) {
  4977.       display->srcdepth=chunky->depth;
  4978.  
  4979.       ret=awiopendisplay(display);
  4980.       if (!ret) {
  4981.         /* try the other mode (fallback) */
  4982.         display->windowmode ^= 1;
  4983.         ret=awiopendisplay(display);
  4984.         if (!ret) display->windowmode ^= 1;
  4985.       }
  4986.     }
  4987.  
  4988.     if (display->srcdepth!=chunky->depth) {
  4989.       if (!display->windowmode) {
  4990.         if ( ( (display->modeid8!=display->modeid16) ||
  4991.                (display->usehamf) ) ||
  4992.              (display->cgfx16bitf) ) {
  4993.           /* screen mode, close screen */
  4994.           awclosedisplay(display);
  4995.           openscr=1;
  4996.         } else {
  4997.           awicleardisplay(display);
  4998.         }
  4999.       }
  5000.  
  5001.       /* change depth */
  5002.       display->srcdepth=chunky->depth;
  5003.  
  5004.       /* ... */
  5005.  
  5006.       if ( (display->windowmode) || (!openscr) ) {
  5007.         /* reload palette */
  5008.         awremap(display);
  5009.         /* and update the display */
  5010.         awreopen(display);
  5011.       } else {
  5012.         ret=awiopendisplay(display);
  5013.         if (!ret) {
  5014.           /* try the original depth */
  5015.           display->srcdepth=odepth;
  5016.           ret=awiopendisplay(display);
  5017.           /* if still failed try opening with new depth
  5018.              on next round */
  5019.           if (!ret) display->srcdepth=chunky->depth;
  5020.         }
  5021.       }
  5022.     }
  5023.  
  5024. #if AW_CGXVIDEOSUPPORT
  5025.  
  5026.     /* handle vlayer */
  5027.  
  5028.     if ( (ret) && (display->usecgxvideo) &&
  5029.          (display->CGXVideoBase) &&
  5030.          (display->windowmode) &&
  5031.          (display->srcdepth==16) &&
  5032.           ((odepth!=chunky->depth) ||  /* if srcdepth *changed* */
  5033.            (display->vlwidth!=chunky->width) ||
  5034.            (display->vlheight!=chunky->height)) ) {
  5035.  
  5036.       CGXVideoBase=display->CGXVideoBase;
  5037.  
  5038.       if (display->vlhandle) {
  5039.         DetachVLayer(display->vlhandle);
  5040.         DeleteVLayerHandle(display->vlhandle);
  5041.         display->vlhandle=NULL;
  5042.       }
  5043.  
  5044.       cvlh_tags[0].ti_Tag=VOA_SrcWidth;  cvlh_tags[0].ti_Data=chunky->width;
  5045.       cvlh_tags[1].ti_Tag=VOA_SrcHeight; cvlh_tags[1].ti_Data=chunky->height;
  5046.       cvlh_tags[2].ti_Tag=VOA_SrcType;   cvlh_tags[2].ti_Data=SRCFMT_RGB16PC;
  5047.       cvlh_tags[3].ti_Tag=TAG_DONE;
  5048.  
  5049.       display->vlhandle=CreateVLayerHandleTagList(
  5050.         display->screen,cvlh_tags);
  5051.  
  5052.       if (display->vlhandle) {
  5053.  
  5054.         cvlh_tags[0].ti_Tag=TAG_DONE;
  5055.  
  5056.         if (AttachVLayerTagList(
  5057.           display->vlhandle,
  5058.           display->window,
  5059.           cvlh_tags)) {
  5060.  
  5061.           /* attached successfully */
  5062.  
  5063.           display->vlwidth=chunky->width;
  5064.           display->vlheight=chunky->height;
  5065.  
  5066.         } else {
  5067.           DeleteVLayerHandle(display->vlhandle);
  5068.           display->vlhandle=NULL;
  5069.         }
  5070.       }
  5071.     }
  5072. #endif
  5073.  
  5074.     awirenderchunky(display,chunky);
  5075.  
  5076.     display->rendering=0;
  5077.   }
  5078. }
  5079.  
  5080. void awrenderchunky_show(struct awdisplay *display,
  5081.   struct awchunky *chunky) {
  5082.  
  5083.   awrenderchunky(display,chunky);
  5084.  
  5085.   /* if in screen mode render chunky twice forcing it
  5086.      visible */
  5087.   if (!display->windowmode) {
  5088.     awrenderchunky(display,chunky);
  5089.   }
  5090. }
  5091.  
  5092. void awfreefile(struct awfile *file) {
  5093.  
  5094.   struct ExecBase *SysBase=(*((struct ExecBase **)4));
  5095.  
  5096.   if (file) {
  5097.     if (file->memory) {
  5098.       if (file->buflen) {
  5099.         /* xpk allocated buffer... */
  5100.         FreeMem(file->memory,file->buflen);
  5101.       } else {
  5102.         /* our allocated buffer */
  5103.         free(file->memory);
  5104.       }
  5105.     }
  5106.     free(file);
  5107.   }
  5108. }
  5109.  
  5110. #if AW_XPKSUPPORT
  5111.  
  5112. ULONG awixpkload(struct awfile *file,const char *name) {
  5113.  
  5114.   struct ExecBase *SysBase=(*((struct ExecBase **)4));
  5115.   struct Library *XpkBase;
  5116.   ULONG ret=0,size,buflen;
  5117.   void *memory;
  5118.   char error[XPKERRMSGSIZE+1];
  5119.   struct TagItem up_tags[8];
  5120.  
  5121.   XpkBase=OpenLibrary("xpkmaster.library",0L);
  5122.   if (XpkBase) {
  5123.  
  5124.     up_tags[0].ti_Tag = XPK_InName;       up_tags[0].ti_Data = (ULONG)name;
  5125.     up_tags[1].ti_Tag = XPK_GetError;     up_tags[1].ti_Data = (ULONG)error;
  5126.     up_tags[2].ti_Tag = XPK_GetOutLen;    up_tags[2].ti_Data = (ULONG)&size;
  5127.     up_tags[3].ti_Tag = XPK_GetOutBuf;    up_tags[3].ti_Data = (ULONG)&memory;
  5128.     up_tags[4].ti_Tag = XPK_GetOutBufLen; up_tags[4].ti_Data = (ULONG)&buflen,
  5129.     up_tags[5].ti_Tag = XPK_OutMemType;   up_tags[5].ti_Data = MEMF_PUBLIC;
  5130.     up_tags[6].ti_Tag = XPK_PassThru;     up_tags[6].ti_Data = 1;
  5131.     up_tags[7].ti_Tag = TAG_DONE;
  5132.  
  5133.     if (!XpkUnpack(up_tags)) {
  5134.  
  5135.       file->memory=malloc(size+63+AW_SANITY);
  5136.       if (file->memory) {
  5137.         file->size=size;
  5138.         file->data=(void *)awalign(file->memory,32);
  5139.         memcpy(file->data,memory,size);
  5140.         FreeMem(memory,buflen);
  5141.       } else {
  5142.         file->size=size;
  5143.         file->memory=memory;
  5144.         file->buflen=buflen;
  5145.       }
  5146.       ret=1;
  5147.  
  5148.     } else {
  5149.       file->memory=NULL; file->buflen=0;
  5150.       printf("awin xpk: %s\n",error);
  5151.     }
  5152.  
  5153.     CloseLibrary(XpkBase);
  5154.   } else {
  5155.     printf("awin: could not open xpkmaster.library\n");
  5156.   }
  5157.   return ret;
  5158. }
  5159. #endif
  5160.  
  5161. struct awfile *awloadfile(const char *name) {
  5162.   struct awfile *file;
  5163.   FILE *fp;
  5164. #if AW_XPKSUPPORT
  5165.   ULONG id;
  5166. #endif
  5167.  
  5168.   fp=fopen(name,"r");
  5169.   if (fp) {
  5170.     if (fseek(fp,0L,SEEK_END)!=-1L) {
  5171.       file=malloc(sizeof(struct awfile));
  5172.       if (file) {
  5173.         memset(file,0,sizeof(struct awfile));
  5174.         file->size=ftell(fp);
  5175.         if (file->size>0) {
  5176.  
  5177. #if AW_XPKSUPPORT
  5178.           if (file->size>12) {
  5179.             rewind(fp);
  5180.             if (fread(&id,1,4,fp)==4) {
  5181.               if (id==('X'<<24|'P'<<16|'K'<<8|'F')) {
  5182.                 if (awixpkload(file,name)) {
  5183.                   fclose(fp);
  5184.                   return file;
  5185.                 }
  5186.               }
  5187.             }
  5188.           }
  5189. #endif
  5190.           file->memory=malloc(file->size+63+AW_SANITY);
  5191.           if (file->memory) {
  5192.             file->data=(void *)awalign(file->memory,32);
  5193.             rewind(fp);
  5194.             if (fread(file->data,1,file->size,fp)==file->size) {
  5195.               fclose(fp);
  5196.               return file;
  5197.             }
  5198.           }
  5199.         }
  5200.         awfreefile(file);
  5201.       }
  5202.     }
  5203.     fclose(fp);
  5204.   } else {
  5205.     printf("awin: could not open %s\n",name);
  5206.   }
  5207.   return NULL;
  5208. }
  5209.